Skip to content

Commit 49955d7

Browse files
committed
deploy: add open-webui-ultimate-stack post, SEO improvements, thumbnail fixes
New blog post covering the Open WebUI Ultimate Stack production deployment with RAG, private search, OCR, MCP tooling, and 35 auto-deployed extensions. SEO improvements: - fix Twitter card image URLs to use absolute paths - add all tag pages to sitemap.xml (50 URLs, up from 12) - add canonical URLs to blog, projects, about, and tags pages - add article:tag to blog post OpenGraph metadata - add noindex to 404 page - add channel image to RSS feed - add start_url/scope/id to PWA manifest Other changes: - add projects tag to homebridge-smartrent-blink and mongodb-replica-set-manager - use aspect-video containers with fill layout for consistent thumbnails - add responsive sizes prop to Card and PostBanner images
1 parent 7ea37bd commit 49955d7

21 files changed

Lines changed: 371 additions & 39 deletions

File tree

app/Main.tsx

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -49,13 +49,15 @@ export default function Home({ posts }: { posts: CoreContent<Blog>[] }) {
4949
aria-hidden="true"
5050
tabIndex={-1}
5151
>
52-
<Image
53-
src={heroImage}
54-
alt=""
55-
width={280}
56-
height={158}
57-
className="w-full rounded-md object-cover sm:w-[280px]"
58-
/>
52+
<div className="relative aspect-video w-full overflow-hidden rounded-md sm:w-[280px]">
53+
<Image
54+
src={heroImage}
55+
alt=""
56+
fill
57+
sizes="(max-width: 640px) 100vw, 280px"
58+
className="object-cover"
59+
/>
60+
</div>
5961
</Link>
6062
)}
6163
<div className="space-y-3">

app/about/page.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ export const metadata: Metadata = genPageMetadata({
1010
title: 'About',
1111
description:
1212
'About BitWise — the engineer behind the blog and the backend systems explored here.',
13+
path: 'about',
1314
})
1415

1516
export default function Page() {

app/blog/[...slug]/page.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ export async function generateMetadata(props: {
6464
url: `${siteMetadata.siteUrl}/blog/${slug}`,
6565
images: ogImages,
6666
authors: authors.length > 0 ? authors : [siteMetadata.author],
67+
tags: post.tags,
6768
},
6869
alternates: {
6970
canonical: post.canonicalUrl || `${siteMetadata.siteUrl}/blog/${slug}`,
@@ -72,7 +73,7 @@ export async function generateMetadata(props: {
7273
card: 'summary_large_image',
7374
title: post.title,
7475
description: post.summary,
75-
images: [heroImage],
76+
images: ogImages.map((img) => img.url),
7677
},
7778
}
7879
}

app/blog/page.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ export const metadata: Metadata = genPageMetadata({
1010
title: 'Blog',
1111
description:
1212
'All posts on BitWise — deep dives into backend engineering, distributed systems, AI/ML, and infrastructure.',
13+
path: 'blog',
1314
})
1415

1516
export default async function BlogPage(props: { searchParams: Promise<{ page: string }> }) {

app/not-found.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
11
import Link from '@/components/Link'
2+
import { Metadata } from 'next'
3+
4+
export const metadata: Metadata = {
5+
title: 'Page Not Found',
6+
robots: { index: false, follow: false },
7+
}
28

39
export default function NotFound() {
410
return (

app/projects/page.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import type { Metadata } from 'next'
66
export const metadata: Metadata = genPageMetadata({
77
title: 'Projects',
88
description: 'Open-source projects and tools built by BitWise.',
9+
path: 'projects',
910
})
1011

1112
export default function Projects() {

app/seo.tsx

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,25 @@ interface PageSEOProps {
55
title: string
66
description?: string
77
image?: string
8+
path?: string
89
alternates?: Metadata['alternates']
910
}
1011

11-
export function genPageMetadata({ title, description, image, ...rest }: PageSEOProps): Metadata {
12+
export function genPageMetadata({
13+
title,
14+
description,
15+
image,
16+
path,
17+
...rest
18+
}: PageSEOProps): Metadata {
19+
const pageUrl = path ? `${siteMetadata.siteUrl}/${path}` : siteMetadata.siteUrl
1220
return {
1321
title,
1422
description: description || siteMetadata.description,
1523
openGraph: {
1624
title: `${title} | ${siteMetadata.title}`,
1725
description: description || siteMetadata.description,
18-
url: siteMetadata.siteUrl,
26+
url: pageUrl,
1927
siteName: siteMetadata.title,
2028
images: image ? [image] : [siteMetadata.socialBanner],
2129
locale: 'en_US',
@@ -27,6 +35,10 @@ export function genPageMetadata({ title, description, image, ...rest }: PageSEOP
2735
images: image ? [image] : [siteMetadata.socialBanner],
2836
creator: '@BitWise_0x',
2937
},
38+
...(path &&
39+
!rest.alternates && {
40+
alternates: { canonical: pageUrl },
41+
}),
3042
...rest,
3143
}
3244
}

app/sitemap.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { MetadataRoute } from 'next'
22
import { allBlogs } from 'contentlayer/generated'
33
import siteMetadata from '@/data/siteMetadata'
4+
import tagData from 'app/tag-data.json'
45

56
export const dynamic = 'force-static'
67

@@ -23,5 +24,10 @@ export default function sitemap(): MetadataRoute.Sitemap {
2324
lastModified: latestDate,
2425
}))
2526

26-
return [...routes, ...blogRoutes]
27+
const tagRoutes = Object.keys(tagData as Record<string, number>).map((tag) => ({
28+
url: `${siteUrl}/tags/${tag}`,
29+
lastModified: latestDate,
30+
}))
31+
32+
return [...routes, ...blogRoutes, ...tagRoutes]
2733
}

app/tag-data.json

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,40 @@
11
{
2+
"ai": 4,
3+
"comfyui": 1,
4+
"python": 2,
5+
"generative-ai": 3,
6+
"automation": 1,
7+
"machine-learning": 1,
8+
"llm": 2,
9+
"data-science": 1,
10+
"prompt-engineering": 1,
211
"homebridge": 1,
312
"homekit": 1,
413
"smartrent": 1,
514
"blink": 1,
615
"typescript": 1,
716
"iot": 1,
817
"smart-home": 1,
9-
"ai": 3,
10-
"projects": 1,
18+
"projects": 4,
1119
"humechat": 1,
1220
"voice-ai": 1,
1321
"hume": 1,
1422
"emotion-detection": 1,
1523
"psychology": 1,
16-
"llm": 1,
17-
"generative-ai": 2,
18-
"python": 2,
19-
"data-science": 1,
20-
"prompt-engineering": 1,
24+
"docker": 2,
25+
"mongodb": 1,
26+
"orchestration": 2,
27+
"devops": 1,
28+
"high-availability": 1,
29+
"database": 1,
30+
"swarm": 2,
31+
"open-webui": 1,
32+
"rag": 1,
33+
"mcp": 1,
2134
"defi": 1,
2235
"blockchain": 1,
2336
"cryptocurrency": 1,
2437
"finance": 1,
2538
"web3": 1,
26-
"trading": 1,
27-
"docker": 1,
28-
"mongodb": 1,
29-
"orchestration": 1,
30-
"devops": 1,
31-
"high-availability": 1,
32-
"database": 1,
33-
"swarm": 1,
34-
"comfyui": 1,
35-
"automation": 1,
36-
"machine-learning": 1
39+
"trading": 1
3740
}

app/tags/page.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ export const metadata = genPageMetadata({
88
title: 'Tags',
99
description:
1010
'Browse all topics on BitWise — backend engineering, distributed systems, AI/ML, blockchain, and infrastructure.',
11+
path: 'tags',
1112
})
1213

1314
export default async function Page() {

0 commit comments

Comments
 (0)