Add page meta tags for search and link previews
This commit is contained in:
1 parent
411fb03c22
commit
fe60a4443d
6 files changed
+94
-17
No files matched your search
@@ -1,19 +1,30 @@
|
||||
<script lang="ts">
|
||||
import type { Snippet } from 'svelte';
|
||||
import { page } from '$app/state';
|
||||
import { profile } from '#lib/content';
|
||||
import { findSitePage } from '#lib/site/pages';
|
||||
import PageMeta, { type PageMetaOptions } from './PageMeta.svelte';
|
||||
|
||||
let { command, title, subtitle, children }: { command: string; title?: string; subtitle?: string; children?: Snippet } =
|
||||
$props();
|
||||
let {
|
||||
command,
|
||||
title,
|
||||
subtitle,
|
||||
description,
|
||||
meta,
|
||||
children
|
||||
}: {
|
||||
command: string;
|
||||
title?: string;
|
||||
subtitle?: string;
|
||||
description?: string;
|
||||
meta?: PageMetaOptions;
|
||||
children?: Snippet;
|
||||
} = $props();
|
||||
|
||||
const metaDescription = $derived(description ?? subtitle ?? findSitePage(page.url.pathname)?.description);
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
{#if title}
|
||||
<title>{title} | {profile.displayName}</title>
|
||||
{/if}
|
||||
{#if subtitle}
|
||||
<meta name="description" content={subtitle} />
|
||||
{/if}
|
||||
</svelte:head>
|
||||
<PageMeta {title} description={metaDescription} {...meta} />
|
||||
|
||||
<header class="page-header">
|
||||
<div class="command">
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
<script lang="ts" module>
|
||||
export type PageMetaOptions = {
|
||||
image?: string;
|
||||
type?: 'website' | 'article' | 'profile';
|
||||
publishedTime?: string;
|
||||
tags?: string[];
|
||||
noIndex?: boolean;
|
||||
};
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
import { page } from '$app/state';
|
||||
import { profile } from '#lib/content';
|
||||
|
||||
let {
|
||||
title,
|
||||
description,
|
||||
image,
|
||||
type = 'website',
|
||||
publishedTime,
|
||||
tags = [],
|
||||
noIndex = false
|
||||
}: PageMetaOptions & { title?: string; description?: string } = $props();
|
||||
|
||||
const fullTitle = $derived(title ? `${title} | ${profile.displayName}` : `${profile.displayName} | Portfolio`);
|
||||
const fullDescription = $derived(description ?? `${profile.title} - ${profile.bio}`);
|
||||
const pageUrl = $derived(`${page.url.origin}${page.url.pathname}`);
|
||||
const imageUrl = $derived(new URL(image ?? profile.photo ?? profile.avatar, page.url.origin).href);
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>{fullTitle}</title>
|
||||
<meta name="description" content={fullDescription} />
|
||||
<link rel="canonical" href={pageUrl} />
|
||||
{#if noIndex}
|
||||
<meta name="robots" content="noindex" />
|
||||
{/if}
|
||||
|
||||
<meta property="og:site_name" content="{profile.displayName}'s Desktop" />
|
||||
<meta property="og:title" content={fullTitle} />
|
||||
<meta property="og:description" content={fullDescription} />
|
||||
<meta property="og:url" content={pageUrl} />
|
||||
<meta property="og:type" content={type} />
|
||||
<meta property="og:image" content={imageUrl} />
|
||||
<meta property="og:image:alt" content={profile.displayName} />
|
||||
|
||||
{#if type === 'article' && publishedTime}
|
||||
<meta property="article:published_time" content={publishedTime} />
|
||||
<meta property="article:author" content={profile.name} />
|
||||
{#each tags as tag (tag)}
|
||||
<meta property="article:tag" content={tag} />
|
||||
{/each}
|
||||
{/if}
|
||||
{#if type === 'profile'}
|
||||
<meta property="profile:username" content={profile.username} />
|
||||
{/if}
|
||||
|
||||
<meta name="twitter:card" content="summary" />
|
||||
<meta name="twitter:title" content={fullTitle} />
|
||||
<meta name="twitter:description" content={fullDescription} />
|
||||
<meta name="twitter:image" content={imageUrl} />
|
||||
</svelte:head>
|
||||
@@ -39,7 +39,7 @@
|
||||
</script>
|
||||
|
||||
<div class="page">
|
||||
<PageHeader command="curl {page.url.pathname}" title="Error {status}" />
|
||||
<PageHeader command="curl {page.url.pathname}" title="Error {status}" meta={{ noIndex: true }} />
|
||||
|
||||
<pre class="ascii" class:server-error={status >= 500}>{asciiDigits.join('\n')}</pre>
|
||||
|
||||
|
||||
@@ -38,6 +38,8 @@
|
||||
{@html themeStyleTag}
|
||||
<link rel="icon" href="/favicon.png" />
|
||||
<meta name="author" content={profile.displayName} />
|
||||
<link rel="apple-touch-icon" href="/favicon.png" />
|
||||
<link rel="alternate" type="application/rss+xml" title="{profile.displayName}'s Blog" href="/blog/rss.xml" />
|
||||
</svelte:head>
|
||||
|
||||
<svelte:window onkeydown={(event) => handleKeybind(event, openWindowIds)} />
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
<script lang="ts">
|
||||
import { profile } from '#lib/content';
|
||||
import PageMeta from '#lib/components/ui/PageMeta.svelte';
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>{profile.displayName} | Portfolio</title>
|
||||
<meta name="description" content="{profile.title} - {profile.bio}" />
|
||||
</svelte:head>
|
||||
<PageMeta type="profile" />
|
||||
@@ -9,7 +9,12 @@
|
||||
|
||||
<div class="page">
|
||||
<article class="article">
|
||||
<PageHeader command="cat ~/blog/{data.post.slug}.md" title={data.post.title} subtitle={data.post.excerpt} />
|
||||
<PageHeader
|
||||
command="cat ~/blog/{data.post.slug}.md"
|
||||
title={data.post.title}
|
||||
subtitle={data.post.excerpt}
|
||||
meta={{ type: 'article', publishedTime: data.post.date, tags: data.post.tags }}
|
||||
/>
|
||||
|
||||
<div class="meta">
|
||||
<a href="/blog">< back to blog</a>
|
||||
|
||||
Reference in new issue
Block a user