Reactive SEO - Global default in root layout, reactive reusable component, data props
This commit is contained in:
parent
8291443c80
commit
0e30d0a539
|
@ -0,0 +1,150 @@
|
||||||
|
<!-- <script lang="ts">
|
||||||
|
import * as conf from '$lib/config'
|
||||||
|
import { getImageLink } from '$lib/images';
|
||||||
|
import type { ExtendedService, ExtendedCategory } from '$lib/types/service';
|
||||||
|
export let data: ExtendedService | ExtendedCategory
|
||||||
|
|
||||||
|
let seoData: ExtendedService | ExtendedCategory
|
||||||
|
|
||||||
|
export let title: string;
|
||||||
|
export let description: string;
|
||||||
|
export let type: string;
|
||||||
|
export let keywords: string;
|
||||||
|
export let image: string;
|
||||||
|
export let canonical: string;
|
||||||
|
export let twitter: {
|
||||||
|
title?: string;
|
||||||
|
description?: string;
|
||||||
|
image?: string;
|
||||||
|
} = {};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<svelte:head>
|
||||||
|
<title>{data.title}</title>
|
||||||
|
<meta name="robots" content="index, follow" />
|
||||||
|
<meta name="googlebot" content="index,follow" />
|
||||||
|
{#if data.description}
|
||||||
|
<meta name="description" content={data.description} />
|
||||||
|
{/if}
|
||||||
|
<meta name="keywords" content={keywords} />
|
||||||
|
{#if data.canonical}
|
||||||
|
<link rel="canonical" href={data.canonical} />
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
<meta property="og:site_name" content="{conf.title}" />
|
||||||
|
<meta property="og:title" content={data.title} />
|
||||||
|
<meta property="og:type" content={data.type ? data.type : 'site'} />
|
||||||
|
{#if data.description}
|
||||||
|
<meta property="og:description" content={data.description} />
|
||||||
|
{/if}
|
||||||
|
{#if data.canonical}
|
||||||
|
<meta property="og:url" content={data.canonical} />
|
||||||
|
{/if}
|
||||||
|
<meta property="og:image" content={getImageLink({id: data.id, h:, w:})} />
|
||||||
|
|
||||||
|
<meta property="fb:admins" content="${conf.FBNumID}" />
|
||||||
|
|
||||||
|
<meta name="twitter:card" content="summary_large_image" />
|
||||||
|
<meta name="twitter:title" content={data.title} />
|
||||||
|
{#if data.description}
|
||||||
|
<meta name="twitter:description" content={data.description} />
|
||||||
|
{/if}
|
||||||
|
<meta name="twitter:image" content={twitter.image || image} />
|
||||||
|
|
||||||
|
<meta property="article:published_time" content={data.frontmatter?.date} />
|
||||||
|
{#each data.frontmatter?.tags as tag (tag)}
|
||||||
|
<meta property="article:tag" content={tag} />
|
||||||
|
{/each}
|
||||||
|
|
||||||
|
</svelte:head> -->
|
||||||
|
<!-- src/lib/components/SEO.svelte -->
|
||||||
|
<script lang="ts">
|
||||||
|
import { page } from '$app/stores';
|
||||||
|
import * as conf from '$lib/config';
|
||||||
|
|
||||||
|
export let seoData: {
|
||||||
|
title: string;
|
||||||
|
description: string;
|
||||||
|
type: string;
|
||||||
|
keywords: string;
|
||||||
|
image: string;
|
||||||
|
canonical?: string;
|
||||||
|
twitter?: {
|
||||||
|
title?: string;
|
||||||
|
description?: string;
|
||||||
|
image?: string;
|
||||||
|
};
|
||||||
|
frontmatter?: {
|
||||||
|
date: string;
|
||||||
|
tags: string[];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
$: title = seoData.title;
|
||||||
|
$: description = seoData.description;
|
||||||
|
$: type = seoData.type;
|
||||||
|
$: keywords = seoData.keywords;
|
||||||
|
$: image = seoData.image;
|
||||||
|
$: canonical = seoData.canonical;
|
||||||
|
$: twitter = seoData.twitter;
|
||||||
|
$: frontmatter = seoData.frontmatter;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<svelte:head>
|
||||||
|
<title>{title}</title>
|
||||||
|
|
||||||
|
<meta name="robots" content="index, follow" />
|
||||||
|
|
||||||
|
<meta name="googlebot" content="index,follow" />
|
||||||
|
|
||||||
|
{#if description}
|
||||||
|
<meta name="description" content={description} />
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
<meta name="keywords" content={keywords} />
|
||||||
|
|
||||||
|
{#if canonical}
|
||||||
|
<link rel="canonical" href={canonical} />
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
<meta property="og:site_name" content={conf.title} />
|
||||||
|
|
||||||
|
<meta property="og:title" content={title} />
|
||||||
|
|
||||||
|
{#if description}
|
||||||
|
<meta property="og:description" content={description} />
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
{#if canonical}
|
||||||
|
<meta property="og:url" content={canonical} />
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
<meta property="og:image" content={image} />
|
||||||
|
|
||||||
|
<meta name="twitter:card" content="summary_large_image" />
|
||||||
|
|
||||||
|
<meta name="twitter:title" content={twitter?.title || title} />
|
||||||
|
|
||||||
|
{#if twitter?.description || description}
|
||||||
|
<meta name="twitter:description" content={twitter?.description || description} />
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
<meta name="twitter:image" content={twitter?.image || image} />
|
||||||
|
|
||||||
|
<!--If there is frontmatter, make it into an article-->
|
||||||
|
{#if frontmatter?}
|
||||||
|
<meta property="og:type" content="article" />
|
||||||
|
{:else}
|
||||||
|
<meta property="og:type" content={type || 'website'} />
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
{#if frontmatter?.date}
|
||||||
|
<meta property="article:published_time" content={frontmatter.date} />
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
{#if frontmatter?.tags}
|
||||||
|
{#each frontmatter.tags as tag}
|
||||||
|
<meta property="article:tag" content={tag} />
|
||||||
|
{/each}
|
||||||
|
{/if}
|
||||||
|
</svelte:head>
|
|
@ -1,20 +0,0 @@
|
||||||
<script lang="ts">
|
|
||||||
import * as conf from '$lib/config'
|
|
||||||
import type { ExtendedServiceItem } from '$lib/types/service';
|
|
||||||
|
|
||||||
export let openGraphData: ExtendedServiceItem;
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<svelte:head>
|
|
||||||
<title>{openGraphData.title}</title>
|
|
||||||
<meta name="description" content={openGraphData.description} />
|
|
||||||
<meta property="og:title" content={openGraphData.title} />
|
|
||||||
<meta property="og:type" content="article" />
|
|
||||||
<meta property="og:description" content={openGraphData.description} />
|
|
||||||
<meta property="og:url" content="{conf.url}{openGraphData.id}" />
|
|
||||||
<meta property="og:image" content={openGraphData.image} />
|
|
||||||
<meta property="article:published_time" content={openGraphData.date} />
|
|
||||||
{#each tags as tag (tag)} <!-- FIX THIS tags is not defined, but it needs to be "eached somehow"-->
|
|
||||||
<meta property="article:tag" content={openGraphData.tag} />
|
|
||||||
{/each}
|
|
||||||
</svelte:head>
|
|
|
@ -1,56 +0,0 @@
|
||||||
<script lang="ts">
|
|
||||||
import * as conf from '$lib/config'
|
|
||||||
import type { ExtendedService, ExtendedCategory } from '$lib/types/service';
|
|
||||||
export let data: ExtendedService | ExtendedCategory
|
|
||||||
|
|
||||||
export let title: string;
|
|
||||||
export let description: string;
|
|
||||||
export let type: string;
|
|
||||||
export let keywords: string;
|
|
||||||
export let image: string;
|
|
||||||
export let canonical: string = undefined;
|
|
||||||
export let twitter: {
|
|
||||||
title?: string;
|
|
||||||
description?: string;
|
|
||||||
image?: string;
|
|
||||||
} = {};
|
|
||||||
conf.</script>
|
|
||||||
|
|
||||||
<svelte:head>
|
|
||||||
<title>{data.title}</title>
|
|
||||||
<meta name="robots" content="index, follow" />
|
|
||||||
<meta name="googlebot" content="index,follow" />
|
|
||||||
{#if data.description}
|
|
||||||
<meta name="description" content={data.description} />
|
|
||||||
{/if}
|
|
||||||
<meta name="keywords" content={keywords} />
|
|
||||||
{#if data.canonical}
|
|
||||||
<link rel="canonical" href={data.canonical} />
|
|
||||||
{/if}
|
|
||||||
|
|
||||||
<meta property="og:site_name" content="{conf.title}" />
|
|
||||||
<meta property="og:title" content={data.title} />
|
|
||||||
<meta property="og:type" content={data.type ? data.type : 'site'} />
|
|
||||||
{#if data.description}
|
|
||||||
<meta property="og:description" content={data.description} />
|
|
||||||
{/if}
|
|
||||||
{#if data.canonical}
|
|
||||||
<meta property="og:url" content={data.canonical} />
|
|
||||||
{/if}
|
|
||||||
<meta property="og:image" content={data.image} />
|
|
||||||
|
|
||||||
<meta property="fb:admins" content="{conf.FBNumID}" />
|
|
||||||
|
|
||||||
<meta name="twitter:card" content="summary_large_image" />
|
|
||||||
<meta name="twitter:title" content={data.title} />
|
|
||||||
{#if data.description}
|
|
||||||
<meta name="twitter:description" content={data.description} />
|
|
||||||
{/if}
|
|
||||||
<meta name="twitter:image" content={twitter.image || image} />
|
|
||||||
|
|
||||||
<meta property="article:published_time" content={data.frontmatter?.date} />
|
|
||||||
{#each data.frontmatter?.tags as tag (tag)}
|
|
||||||
<meta property="article:tag" content={tag} />
|
|
||||||
{/each}
|
|
||||||
|
|
||||||
</svelte:head>
|
|
|
@ -27,24 +27,34 @@
|
||||||
import MainFooter from '$lib/components/MainFooter.svelte';
|
import MainFooter from '$lib/components/MainFooter.svelte';
|
||||||
|
|
||||||
// SEO Meta tags
|
// SEO Meta tags
|
||||||
const metaDefaults = {
|
import SEO from '$lib/components/SEO.svelte'
|
||||||
title: 'BeautySalon',
|
|
||||||
description: 'BeautySalon Popis.',
|
$: seoData = $page.data.seoData || {
|
||||||
image: 'https://user-images.githubusercontent.com/1509726/212382766-f29b9c9a-82e3-44c2-b911-b17a9197e5b9.jpg'
|
title: 'KKosmetickySalon - Klára Morinová',
|
||||||
};
|
description: 'Přijeďte si ke mně pro odbornou péči o Vaši pleť. Jsem certifikovaná kosmetička a makeup artistka, provádím Permanentní Make-up, vizážistiku, ošetřovací a zeštihlovací procedury, a mnoho dalšího... Vše s ohledem na vaše zdraví. Zarezervujte si péči o svůj vzhled přes moje stránky nyní!',
|
||||||
const meta = {
|
keywords: 'kosmetika, vizáž, pleť, Písek, kosmetička, permanentní makeup, ',
|
||||||
title: metaDefaults.title,
|
image: '/logo-text.png',
|
||||||
description: metaDefaults.description,
|
type: 'website',
|
||||||
image: metaDefaults.image,
|
};
|
||||||
// Article
|
|
||||||
article: { publishTime: '', modifiedTime: '', author: '' },
|
// const metaDefaults = {
|
||||||
// Twitter
|
// title: 'BeautySalon',
|
||||||
twitter: {
|
// description: 'BeautySalon Popis.',
|
||||||
title: metaDefaults.title,
|
// image: 'https://user-images.githubusercontent.com/1509726/212382766-f29b9c9a-82e3-44c2-b911-b17a9197e5b9.jpg'
|
||||||
description: metaDefaults.description,
|
// };
|
||||||
image: metaDefaults.image
|
// const meta = {
|
||||||
}
|
// title: metaDefaults.title,
|
||||||
};
|
// description: metaDefaults.description,
|
||||||
|
// image: metaDefaults.image,
|
||||||
|
// // Article
|
||||||
|
// article: { publishTime: '', modifiedTime: '', author: '' },
|
||||||
|
// // Twitter
|
||||||
|
// twitter: {
|
||||||
|
// title: metaDefaults.title,
|
||||||
|
// description: metaDefaults.description,
|
||||||
|
// image: metaDefaults.image
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
|
||||||
|
|
||||||
// Scroll to anchor
|
// Scroll to anchor
|
||||||
|
@ -63,15 +73,15 @@
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!-- SEO -->
|
<!-- SEO -->
|
||||||
<svelte:head>
|
<!-- <svelte:head>
|
||||||
<title>{meta.title}</title>
|
<title>{meta.title}</title>
|
||||||
<!-- Meta Tags -->
|
Meta Tags
|
||||||
<meta name="title" content={meta.title} />
|
<meta name="title" content={meta.title} />
|
||||||
<meta name="description" content={meta.description} />
|
<meta name="description" content={meta.description} />
|
||||||
<meta name="keywords" content="krása, kosmetika, permanentní makeup, revitalizace pleti, oprava pleti, salón, kosmetička, kosmetický salón, Písek, obočí, vytrhání, natočení řas, řasy" />
|
<meta name="keywords" content="krása, kosmetika, permanentní makeup, revitalizace pleti, oprava pleti, salón, kosmetička, kosmetický salón, Písek, obočí, vytrhání, natočení řas, řasy" />
|
||||||
<meta name="theme-color" content="#242c46" />
|
<meta name="theme-color" content="#242c46" />
|
||||||
<meta name="author" content="Klára Morinová" />
|
<meta name="author" content="Klára Morinová" />
|
||||||
<!-- Open Graph - https://ogp.me/ -->
|
Open Graph - https://ogp.me/
|
||||||
<meta property="og:site_name" content="BeautySalon" />
|
<meta property="og:site_name" content="BeautySalon" />
|
||||||
<meta property="og:type" content="website" />
|
<meta property="og:type" content="website" />
|
||||||
<meta property="og:url" content="https://www.beautysalon.cz{$page.url.pathname}" />
|
<meta property="og:url" content="https://www.beautysalon.cz{$page.url.pathname}" />
|
||||||
|
@ -84,12 +94,12 @@
|
||||||
<meta property="og:image:width" content="1707" />
|
<meta property="og:image:width" content="1707" />
|
||||||
<meta property="og:image:height" content="1233" />
|
<meta property="og:image:height" content="1233" />
|
||||||
|
|
||||||
<!-- Open Graph: Twitter -->
|
Open Graph: Twitter
|
||||||
<meta name="twitter:title" content={meta.twitter.title} />
|
<meta name="twitter:title" content={meta.twitter.title} />
|
||||||
<meta name="twitter:description" content={meta.twitter.description} />
|
<meta name="twitter:description" content={meta.twitter.description} />
|
||||||
<meta name="twitter:image" content={meta.twitter.image} />
|
<meta name="twitter:image" content={meta.twitter.image} />
|
||||||
</svelte:head>
|
</svelte:head> -->
|
||||||
|
<SEO {seoData}/>
|
||||||
<!-- <Analytics /> -->
|
<!-- <Analytics /> -->
|
||||||
<!-- App Shell -->
|
<!-- App Shell -->
|
||||||
<Drawer />
|
<Drawer />
|
||||||
|
|
Loading…
Reference in New Issue