Skip to content

Commit a9a13e9

Browse files
seo optimization and posthog cleanup
1 parent b7c8f27 commit a9a13e9

13 files changed

Lines changed: 747 additions & 54 deletions

File tree

astro.config.mjs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// @ts-check
22
import { defineConfig } from 'astro/config';
33
import tailwindcss from '@tailwindcss/vite';
4+
import sitemap from '@astrojs/sitemap';
45
import favicons from 'astro-favicons';
56
import wikiImagePlugin from './src/plugins/wikiImagePlugin.mjs';
67

@@ -24,6 +25,7 @@ export default defineConfig({
2425
plugins: [tailwindcss()]
2526
},
2627
integrations: [
28+
sitemap(),
2729
favicons({
2830
input: {
2931
favicons: [

package-lock.json

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

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,12 @@
1111
"dependencies": {
1212
"@astrojs/prism": "^4.0.1",
1313
"@astrojs/rss": "^4.0.17",
14+
"@astrojs/sitemap": "^3.7.1",
1415
"@tailwindcss/vite": "^4.1.18",
1516
"astro": "^6.0.7",
1617
"astro-favicons": "^3.1.5",
1718
"markdown-it": "^14.1.0",
19+
"posthog-js": "^1.363.1",
1820
"sanitize-html": "^2.17.0",
1921
"tailwindcss": "^4.1.18"
2022
},

public/og-image.svg

Lines changed: 24 additions & 0 deletions
Loading

public/robots.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
User-agent: *
2+
Allow: /
3+
4+
Sitemap: https://kyleundefined.dev/sitemap-index.xml

src/components/PostCard.astro

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ interface Props {
88
99
const { post } = Astro.props;
1010
const { title, description, pubDate } = post.data;
11-
const readingTime = getReadingTimeLabel(post.body);
11+
const readingTime = getReadingTimeLabel(post.body ?? '');
1212
---
1313

1414
<a href={`/blog/${post.id}`} class="group flex flex-col h-full bg-blog-code-bg rounded-2xl overflow-hidden shadow-sm hover:shadow-md duration-300 border border-blog-border hover:border-blog-accent transition-all duration-300">

src/components/posthog.astro

Lines changed: 8 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,10 @@
11
---
22
---
3-
<script is:inline type="text/javascript" id="posthog-js">
4-
if (!window.__posthog_initialized) {
5-
window.__posthog_initialized = true;
6-
7-
!(function(t, e) {
8-
var o, n, p, r;
9-
e.__SV ||
10-
((window.posthog = e),
11-
(e._i = []),
12-
(e.init = function(i, s, a) {
13-
function g(t, e) {
14-
var o = e.split('.');
15-
2 == o.length && ((t = t[o[0]]), (e = o[1])),
16-
(t[e] = function() {
17-
t.push([e].concat(Array.prototype.slice.call(arguments, 0)));
18-
});
19-
}
20-
((p = t.createElement('script')).type = 'text/javascript'),
21-
(p.crossOrigin = 'anonymous'),
22-
(p.async = true),
23-
(p.src = s.api_host + '/static/array.js'),
24-
(r = t.getElementsByTagName('script')[0]).parentNode.insertBefore(p, r);
25-
var u = e;
26-
void 0 !== a ? (u = e[a] = []) : (a = 'posthog');
27-
u.people = u.people || [];
28-
u.toString = function(t) {
29-
var e = 'posthog';
30-
return 'posthog' !== a && (e += '.' + a), t || (e += ' (stub)'), e;
31-
};
32-
u.people.toString = function() {
33-
return u.toString(1) + '.people (stub)';
34-
};
35-
o =
36-
'capture identify alias people.set people.set_once set_config register register_once unregister opt_out_capturing has_opted_out_capturing opt_in_capturing reset isFeatureEnabled onFeatureFlags getFeatureFlag getFeatureFlagPayload reloadFeatureFlags group updateEarlyAccessFeatureEnrollment getEarlyAccessFeatures getActiveMatchingSurveys getSurveys getNextSurveyStep onSessionId'.split(
37-
' '
38-
);
39-
for (n = 0; n < o.length; n++) g(u, o[n]);
40-
e._i.push([i, s, a]);
41-
}),
42-
(e.__SV = 1));
43-
})(document, window.posthog || []);
44-
posthog.init('phc_TnomHuSZzsyUfDZeTqAujhtyGaTJHU2uG0caEImfN0c', { api_host: 'https://us.i.posthog.com', defaults: '2025-05-24' });
45-
}
46-
</script>
3+
<script>
4+
import posthog from 'posthog-js'
5+
6+
posthog.init('phc_TnomHuSZzsyUfDZeTqAujhtyGaTJHU2uG0caEImfN0c', {
7+
api_host: 'https://us.i.posthog.com',
8+
defaults: '2026-01-30'
9+
})
10+
</script>

src/layouts/Layout.astro

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,13 @@ import '../styles/global.css';
88
interface Props {
99
title: string;
1010
description?: string;
11+
image?: string;
1112
}
1213
13-
const { title, description = "Just a dude who enjoys writing code & learning;" } = Astro.props;
14+
const { title, description = "Kyle Undefined - self-taught dev writing code, learning new tech, and sharing the journey.", image = "/og-image.svg" } = Astro.props;
15+
const canonicalPath = Astro.url.pathname.replace(/\/index\.html$/, '/').replace(/\.html$/, '');
16+
const canonicalUrl = new URL(canonicalPath, Astro.site).href;
17+
const ogImageUrl = new URL(image, Astro.site).href;
1418
---
1519

1620
<!doctype html>
@@ -22,17 +26,25 @@ const { title, description = "Just a dude who enjoys writing code & learning;" }
2226
<meta name="viewport" content="width=device-width" />
2327
<meta name="generator" content={Astro.generator} />
2428

29+
<!-- Canonical -->
30+
<link rel="canonical" href={canonicalUrl} />
31+
2532
<!-- Open Graph / Facebook -->
2633
<meta property="og:type" content="website" />
27-
<meta property="og:url" content={Astro.url} />
34+
<meta property="og:url" content={canonicalUrl} />
35+
<meta property="og:site_name" content="Kyle Undefined" />
2836
<meta property="og:title" content={title} />
2937
<meta property="og:description" content={description} />
38+
<meta property="og:image" content={ogImageUrl} />
39+
<meta property="og:image:width" content="1200" />
40+
<meta property="og:image:height" content="630" />
3041

3142
<!-- Twitter -->
3243
<meta property="twitter:card" content="summary_large_image" />
33-
<meta property="twitter:url" content={Astro.url} />
44+
<meta property="twitter:url" content={canonicalUrl} />
3445
<meta property="twitter:title" content={title} />
3546
<meta property="twitter:description" content={description} />
47+
<meta property="twitter:image" content={ogImageUrl} />
3648

3749
<!-- RSS -->
3850
<link rel="alternate" type="application/rss+xml" title="kyleundefined.dev" href={new URL("rss.xml", Astro.site).href} />

src/pages/404.astro

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import Layout from '../layouts/Layout.astro';
33
---
44

5-
<Layout title='404 | KyleUndefined.dev' description='404 Page'>
5+
<Layout title='404 | Kyle Undefined' description='404 Page'>
66
<section class="py-12 md:py-10">
77
<div class="space-y-6">
88
<h1 class="text-4xl md:text-6xl font-bold tracking-tighter">

src/pages/blog/[...slug].astro

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,42 @@ type Props = CollectionEntry<'blog'>;
1515
const post = Astro.props;
1616
const { Content, headings } = await render(post);
1717
const tocHeadings = headings.filter((heading) => heading.depth >= 2 && heading.depth <= 3);
18-
const readingTime = getReadingTimeLabel(post.body);
18+
const readingTime = getReadingTimeLabel(post.body ?? '');
1919
---
2020

21-
<Layout title={post.data.title} description={post.data.description}>
21+
<Layout title={`${post.data.title} | Kyle Undefined`} description={post.data.description}>
22+
<script type="application/ld+json" set:html={JSON.stringify({
23+
"@context": "https://schema.org",
24+
"@graph": [
25+
{
26+
"@type": "BlogPosting",
27+
"headline": post.data.title,
28+
"description": post.data.description,
29+
"datePublished": post.data.pubDate.toISOString(),
30+
...(post.data.updatedDate && { "dateModified": post.data.updatedDate.toISOString() }),
31+
"url": `https://kyleundefined.dev/blog/${post.id}`,
32+
"inLanguage": "en",
33+
"author": {
34+
"@type": "Person",
35+
"name": "Kyle Undefined",
36+
"url": "https://kyleundefined.dev"
37+
},
38+
"publisher": {
39+
"@type": "Person",
40+
"name": "Kyle Undefined",
41+
"url": "https://kyleundefined.dev"
42+
}
43+
},
44+
{
45+
"@type": "BreadcrumbList",
46+
"itemListElement": [
47+
{ "@type": "ListItem", "position": 1, "name": "Home", "item": "https://kyleundefined.dev" },
48+
{ "@type": "ListItem", "position": 2, "name": "Blog", "item": "https://kyleundefined.dev/blog" },
49+
{ "@type": "ListItem", "position": 3, "name": post.data.title }
50+
]
51+
}
52+
]
53+
})} />
2254
<div
2355
data-reading-progress
2456
style="transform: scaleX(0);"

0 commit comments

Comments
 (0)