Skip to content

Commit ef29a8f

Browse files
author
Lars Peters
committed
Meta data improvements
1 parent a1cf028 commit ef29a8f

6 files changed

Lines changed: 108 additions & 29 deletions

File tree

bun.lock

Lines changed: 37 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
"astro": "^6.1.8",
2222
"dayjs": "^1.11.19",
2323
"lodash.kebabcase": "^4.1.1",
24+
"markdown-it": "^14.1.1",
25+
"sanitize-html": "^2.17.3",
2426
"satori": "^0.18.3",
2527
"sharp": "^0.34.5",
2628
"slugify": "^1.6.6",
@@ -32,6 +34,8 @@
3234
"@shikijs/transformers": "^3.20.0",
3335
"@tailwindcss/typography": "^0.5.19",
3436
"@types/lodash.kebabcase": "^4.1.9",
37+
"@types/markdown-it": "^14.1.2",
38+
"@types/sanitize-html": "^2.16.1",
3539
"@typescript-eslint/parser": "^8.51.0",
3640
"eslint": "^9.39.2",
3741
"eslint-plugin-astro": "^1.5.0",

src/layouts/Layout.astro

Lines changed: 47 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ type Props = {
1515
pubDatetime?: Date;
1616
modDatetime?: Date | null;
1717
scrollSmooth?: boolean;
18+
noindex?: boolean;
1819
};
1920
2021
const {
@@ -27,25 +28,40 @@ const {
2728
pubDatetime,
2829
modDatetime,
2930
scrollSmooth = false,
31+
noindex = false,
3032
} = Astro.props;
3133
3234
const socialImageURL = new URL(ogImage, Astro.url);
33-
34-
const structuredData = {
35-
"@context": "https://schema.org",
36-
"@type": "BlogPosting",
37-
headline: `${title}`,
38-
image: `${socialImageURL}`,
39-
datePublished: `${pubDatetime?.toISOString()}`,
40-
...(modDatetime && { dateModified: modDatetime.toISOString() }),
41-
author: [
42-
{
43-
"@type": "Person",
44-
name: `${author}`,
45-
...(profile && { url: profile }),
46-
},
47-
],
48-
};
35+
const isPost = !!pubDatetime;
36+
const ogLocale = (SITE.lang as string) === "de" ? "de_DE" : "en_US";
37+
38+
const structuredData = isPost
39+
? {
40+
"@context": "https://schema.org",
41+
"@type": "BlogPosting",
42+
mainEntityOfPage: {
43+
"@type": "WebPage",
44+
"@id": canonicalURL.toString(),
45+
},
46+
headline: title,
47+
description,
48+
image: socialImageURL.toString(),
49+
datePublished: pubDatetime!.toISOString(),
50+
...(modDatetime && { dateModified: modDatetime.toISOString() }),
51+
author: [
52+
{
53+
"@type": "Person",
54+
name: author,
55+
...(profile && { url: profile }),
56+
},
57+
],
58+
publisher: {
59+
"@type": "Person",
60+
name: SITE.author,
61+
url: SITE.profile,
62+
},
63+
}
64+
: null;
4965
---
5066

5167
<!doctype html>
@@ -72,9 +88,13 @@ const structuredData = {
7288
<meta name="title" content={title} />
7389
<meta name="description" content={description} />
7490
<meta name="author" content={author} />
91+
{noindex && <meta name="robots" content="noindex, nofollow" />}
7592
<link rel="sitemap" href="/sitemap-index.xml" />
7693

7794
<!-- Open Graph / Facebook -->
95+
<meta property="og:type" content={isPost ? "article" : "website"} />
96+
<meta property="og:site_name" content={SITE.title} />
97+
<meta property="og:locale" content={ogLocale} />
7898
<meta property="og:title" content={title} />
7999
<meta property="og:description" content={description} />
80100
<meta property="og:url" content={canonicalURL} />
@@ -105,12 +125,16 @@ const structuredData = {
105125
<meta property="twitter:description" content={description} />
106126
<meta property="twitter:image" content={socialImageURL} />
107127

108-
<!-- Google JSON-LD Structured data -->
109-
<script
110-
type="application/ld+json"
111-
is:inline
112-
set:html={JSON.stringify(structuredData)}
113-
/>
128+
<!-- Google JSON-LD Structured data (only for blog posts) -->
129+
{
130+
structuredData && (
131+
<script
132+
type="application/ld+json"
133+
is:inline
134+
set:html={JSON.stringify(structuredData)}
135+
/>
136+
)
137+
}
114138

115139
<!-- Enable RSS feed auto-discovery -->
116140
<!-- https://docs.astro.build/en/recipes/rss/#enabling-rss-feed-auto-discovery -->
@@ -121,7 +145,7 @@ const structuredData = {
121145
href={new URL("rss.xml", Astro.site)}
122146
/>
123147

124-
<meta name="theme-color" content="" />
148+
<meta name="theme-color" content="#fdfdfd" />
125149

126150
{
127151
// If PUBLIC_GOOGLE_SITE_VERIFICATION is set in the environment variable,

src/layouts/PostDetails.astro

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,9 @@ const nextPost =
115115
<img
116116
src={coverUrl}
117117
alt={title}
118-
class="mt-6 max-h-96 w-full rounded border border-border object-cover"
118+
width="1200"
119+
height="600"
120+
class="mt-6 aspect-[2/1] w-full rounded border border-border object-cover"
119121
loading="eager"
120122
/>
121123
)

src/pages/rss.xml.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,36 @@
11
import rss from "@astrojs/rss";
22
import { getCollection } from "astro:content";
3+
import MarkdownIt from "markdown-it";
4+
import sanitizeHtml from "sanitize-html";
35
import { getPath } from "@/utils/getPath";
46
import getSortedPosts from "@/utils/getSortedPosts";
57
import { SITE } from "@/config";
68

9+
const parser = new MarkdownIt({ html: true, linkify: true });
10+
711
export async function GET() {
812
const posts = await getCollection("blog");
913
const sortedPosts = getSortedPosts(posts);
1014
return rss({
1115
title: SITE.title,
1216
description: SITE.desc,
1317
site: SITE.website,
14-
items: sortedPosts.map(({ data, id, filePath }) => ({
18+
xmlns: { atom: "http://www.w3.org/2005/Atom" },
19+
customData: `<language>${SITE.lang}-${(SITE.lang as string) === "de" ? "DE" : "US"}</language>
20+
<atom:link href="${new URL("rss.xml", SITE.website).href}" rel="self" type="application/rss+xml" />`,
21+
items: sortedPosts.map(({ data, id, filePath, body }) => ({
1522
link: getPath(id, filePath),
1623
title: data.title,
1724
description: data.description,
1825
pubDate: new Date(data.modDatetime ?? data.pubDatetime),
26+
categories: data.tags,
27+
content: sanitizeHtml(parser.render(body ?? ""), {
28+
allowedTags: sanitizeHtml.defaults.allowedTags.concat(["img"]),
29+
allowedAttributes: {
30+
...sanitizeHtml.defaults.allowedAttributes,
31+
img: ["src", "alt", "title", "width", "height"],
32+
},
33+
}),
1934
})),
2035
});
2136
}

src/pages/search.astro

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { SITE } from "@/config";
99
const backUrl = SITE.showBackButton ? `${Astro.url.pathname}` : "/";
1010
---
1111

12-
<Layout title={`Search | ${SITE.title}`}>
12+
<Layout title={`Search | ${SITE.title}`} noindex={true}>
1313
<Header />
1414
<Main pageTitle="Search" pageDesc="Search any article ...">
1515
<div id="pagefind-search" transition:persist data-backurl={backUrl}></div>

0 commit comments

Comments
 (0)