diff --git a/src/lib/blog-utils.ts b/src/lib/blog-utils.ts index 158d8bd..7a105f2 100644 --- a/src/lib/blog-utils.ts +++ b/src/lib/blog-utils.ts @@ -302,7 +302,7 @@ const POST_BASE = "/post"; export function postHref(post: PostEntry): string { const slug = post.slug ?? post._slug ?? ""; const norm = (slug ?? "").replace(/^\//, "").trim(); - return norm ? `${POST_BASE}/${encodeURIComponent(norm)}` : POST_BASE; + return norm ? `${POST_BASE}/${encodeURIComponent(norm)}/` : `${POST_BASE}/`; } export function formatPostDate(value: string | undefined): string { diff --git a/src/lib/components/BlogOverview.svelte b/src/lib/components/BlogOverview.svelte index c59c225..c888ae4 100644 --- a/src/lib/components/BlogOverview.svelte +++ b/src/lib/components/BlogOverview.svelte @@ -108,8 +108,8 @@ } function tagHref(tagSlug: string | null): string { - if (!tagSlug) return basePath; - return `${basePath}/tag/${encodeURIComponent(tagSlug)}`; + if (!tagSlug) return `${basePath}/`; + return `${basePath}/tag/${encodeURIComponent(tagSlug)}/`; } const totalCount = $derived(totalPosts); diff --git a/src/lib/components/Pagination.svelte b/src/lib/components/Pagination.svelte index 0230569..c5f5b07 100644 --- a/src/lib/components/Pagination.svelte +++ b/src/lib/components/Pagination.svelte @@ -19,8 +19,8 @@ } = $props(); function tagHref(tagSlug: string | null): string { - if (!tagSlug) return basePath; - return `${basePath}/tag/${encodeURIComponent(tagSlug)}`; + if (!tagSlug) return `${basePath}/`; + return `${basePath}/tag/${encodeURIComponent(tagSlug)}/`; } function pageHref(page: number): string { @@ -28,7 +28,7 @@ const tagPart = activeTag ? `/tag/${encodeURIComponent(activeTag)}` : ""; - return `${basePath}${tagPart}/page/${page}`; + return `${basePath}${tagPart}/page/${page}/`; } const showPagination = $derived(totalPages > 1); diff --git a/src/lib/components/Tags.svelte b/src/lib/components/Tags.svelte index c7ac3c2..2ce7378 100644 --- a/src/lib/components/Tags.svelte +++ b/src/lib/components/Tags.svelte @@ -51,7 +51,7 @@ diff --git a/src/routes/+layout.server.ts b/src/routes/+layout.server.ts index b061801..49b578a 100644 --- a/src/routes/+layout.server.ts +++ b/src/routes/+layout.server.ts @@ -1,4 +1,7 @@ import type { LayoutServerLoad } from './$types'; + +export const trailingSlash = 'always'; + import { getNavigationByKey, NavigationKeys, @@ -71,7 +74,7 @@ export const load: LayoutServerLoad = async ({ locals }) => { for (const p of posts) { const label = p.linkName ?? p.headline ?? p.slug ?? p._slug ?? ''; const urlSlug = normalizeSlug(p.slug ?? p._slug); - const canonical = urlSlug ? `/post/${encodeURIComponent(urlSlug)}` : ''; + const canonical = urlSlug ? `/post/${encodeURIComponent(urlSlug)}/` : ''; const keySlug = normalizeSlug(p.slug); const keyUnderscore = normalizeSlug(p._slug); if (keySlug) { @@ -111,7 +114,8 @@ export const load: LayoutServerLoad = async ({ locals }) => { .split('/') .filter(Boolean) .map((seg) => encodeURIComponent(seg)) - .join('/'); + .join('/') + + '/'; const href = postHref ?? pageHref; headerLinks.push({ href, label }); } diff --git a/src/routes/api/search-index/+server.ts b/src/routes/api/search-index/+server.ts index 06337d1..82c8049 100644 --- a/src/routes/api/search-index/+server.ts +++ b/src/routes/api/search-index/+server.ts @@ -25,7 +25,7 @@ export type SearchHit = { function pageHref(p: { slug?: string; _slug?: string }): string { const raw = (p.slug ?? p._slug ?? '').replace(/^\//, '').trim(); if (!raw || raw === 'home') return '/'; - return '/' + raw.split('/').filter(Boolean).map(encodeURIComponent).join('/'); + return '/' + raw.split('/').filter(Boolean).map(encodeURIComponent).join('/') + '/'; } export const GET: RequestHandler = async () => { diff --git a/src/routes/blog/page/[page]/+page.server.ts b/src/routes/blog/page/[page]/+page.server.ts index ce3ab13..d69652d 100644 --- a/src/routes/blog/page/[page]/+page.server.ts +++ b/src/routes/blog/page/[page]/+page.server.ts @@ -2,5 +2,5 @@ import type { PageServerLoad } from './$types'; import { redirect } from '@sveltejs/kit'; export const load: PageServerLoad = async ({ params }) => { - redirect(301, `/posts/page/${encodeURIComponent(params.page)}`); + redirect(301, `/posts/page/${encodeURIComponent(params.page)}/`); }; diff --git a/src/routes/blog/tag/[tag]/+page.server.ts b/src/routes/blog/tag/[tag]/+page.server.ts index 99a5b44..578b8c1 100644 --- a/src/routes/blog/tag/[tag]/+page.server.ts +++ b/src/routes/blog/tag/[tag]/+page.server.ts @@ -2,5 +2,5 @@ import type { PageServerLoad } from './$types'; import { redirect } from '@sveltejs/kit'; export const load: PageServerLoad = async ({ params }) => { - redirect(301, `/posts/tag/${encodeURIComponent(params.tag)}`); + redirect(301, `/posts/tag/${encodeURIComponent(params.tag)}/`); }; diff --git a/src/routes/post/[slug]/+page.server.ts b/src/routes/post/[slug]/+page.server.ts index 350e634..c7d0573 100644 --- a/src/routes/post/[slug]/+page.server.ts +++ b/src/routes/post/[slug]/+page.server.ts @@ -121,7 +121,7 @@ export const load: PageServerLoad = async ({ params, locals, url }) => { socialImage: postImageUrl ?? undefined, breadcrumbItems: [ { href: '/', label: 'Start' }, - { href: '/posts', label: 'Beiträge' }, + { href: '/posts/', label: 'Beiträge' }, { label: post.headline ?? post.linkName ?? post.slug ?? post._slug ?? slug }, ], }; diff --git a/src/routes/posts/tag/[tag]/+page.server.ts b/src/routes/posts/tag/[tag]/+page.server.ts index 877158c..4eb9ec3 100644 --- a/src/routes/posts/tag/[tag]/+page.server.ts +++ b/src/routes/posts/tag/[tag]/+page.server.ts @@ -13,7 +13,7 @@ export const load: PageServerLoad = async ({ params, locals }) => { seoDescription: `Beiträge zum Thema ${result.tagName}.`, breadcrumbItems: [ { href: '/', label: t(translations, T.nav_start) }, - { href: '/posts', label: t(translations, T.nav_posts) }, + { href: '/posts/', label: t(translations, T.nav_posts) }, { label: result.tagName ?? '' }, ], }; diff --git a/src/routes/posts/tag/[tag]/page/[page]/+page.server.ts b/src/routes/posts/tag/[tag]/page/[page]/+page.server.ts index b16c061..3821087 100644 --- a/src/routes/posts/tag/[tag]/page/[page]/+page.server.ts +++ b/src/routes/posts/tag/[tag]/page/[page]/+page.server.ts @@ -14,8 +14,8 @@ export const load: PageServerLoad = async ({ params, locals }) => { seoDescription: `Beiträge zum Thema ${result.tagName}.`, breadcrumbItems: [ { href: '/', label: t(translations, T.nav_start) }, - { href: '/posts', label: t(translations, T.nav_posts) }, - { href: `/posts/tag/${encodeURIComponent(params.tag)}`, label: result.tagName ?? '' }, + { href: '/posts/', label: t(translations, T.nav_posts) }, + { href: `/posts/tag/${encodeURIComponent(params.tag)}/`, label: result.tagName ?? '' }, ], }; }; diff --git a/src/routes/sitemap.xml/+server.ts b/src/routes/sitemap.xml/+server.ts index b6527ae..f2f9e9c 100644 --- a/src/routes/sitemap.xml/+server.ts +++ b/src/routes/sitemap.xml/+server.ts @@ -15,7 +15,8 @@ function pageHref(canonical: string): string { .split('/') .filter(Boolean) .map((seg) => encodeURIComponent(seg)) - .join('/') + .join('/') + + '/' ); } @@ -40,8 +41,8 @@ export const GET: RequestHandler = async ({ url }) => { const urls: { loc: string; lastmod?: string; changefreq?: string; priority?: string }[] = [ { loc: `${site}/`, changefreq: 'daily', priority: '1.0' }, - { loc: `${site}/posts`, changefreq: 'daily', priority: '0.8' }, - { loc: `${site}/blog`, changefreq: 'daily', priority: '0.8' }, + { loc: `${site}/posts/`, changefreq: 'daily', priority: '0.8' }, + { loc: `${site}/blog/`, changefreq: 'daily', priority: '0.8' }, ]; try {