Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,14 @@ package
.vscode
.env.local
.env.*.local
*.pem

# Playwright
/test-results
/playwright-report
/blob-report
/playwright/.cache

*.pem
*.pub
*.sec

Expand Down
2 changes: 2 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ build/
.svelte-kit/
dist/
node_modules/
test-results/
playwright-report/

# Lockfiles
package-lock.json
Expand Down
11 changes: 11 additions & 0 deletions src/routes/(marketing)/+layout.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,17 @@
})
</script>

<svelte:head>

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good call making the layout the single source of truth for RSS autodiscovery. One leftover for consistency: src/routes/(marketing)/blog/[slug]/+page.svelte (~line 67) still carries the identical <svelte:head> RSS block you removed from blog/+page.svelte. It's not a duplicate-render bug — Svelte dedupes identical svelte:head elements, and the prerendered output was verified to have exactly one rss link per page — but removing it here too keeps this layout as the only source. Optional, non-blocking.

<!-- Site-wide RSS autodiscovery so feed readers pointed at any marketing
page (including the root domain) find the blog feed. -->
<link
rel="alternate"
type="application/rss+xml"
title="PostGuard Blog RSS Feed"
href="/blog/rss.xml"
/>
</svelte:head>

{#if !$isLoading}
<a class="sr-only sr-only-focusable skip-link" href="#main-content">
{$_('common.skipToMain', { default: 'Skip to main content' })}
Expand Down
9 changes: 0 additions & 9 deletions src/routes/(marketing)/blog/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -54,15 +54,6 @@
jsonLd={blogJsonLd}
/>

<svelte:head>
<link
rel="alternate"
type="application/rss+xml"
title="PostGuard Blog RSS Feed"
href="/blog/rss.xml"
/>
</svelte:head>

<div class="blog-index">
<div class="header">
<h1>Blog</h1>
Expand Down
9 changes: 0 additions & 9 deletions src/routes/(marketing)/blog/[slug]/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -64,15 +64,6 @@
jsonLd={articleJsonLd}
/>

<svelte:head>
<link
rel="alternate"
type="application/rss+xml"
title="PostGuard Blog RSS Feed"
href="/blog/rss.xml"
/>
</svelte:head>

<article class="blog-post">
<header>
<div class="meta">
Expand Down
30 changes: 30 additions & 0 deletions tests/rss-autodiscovery.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { expect, test } from '@playwright/test'

const RSS_LINK =
'head > link[rel="alternate"][type="application/rss+xml"][href="/blog/rss.xml"]'

// Regression test for the site-wide RSS autodiscovery link (issue
// encryption4all/postguard-business#58). The autodiscovery <link> lives in the
// marketing layout head, so every public page must advertise the blog feed
// exactly once — including non-blog pages and blog pages, which must not carry
// a leftover per-page duplicate.
for (const path of ['/', '/about/', '/blog/']) {
test(`RSS autodiscovery link is present exactly once on ${path}`, async ({
page,
}) => {
await page.goto(path)
await expect(page.locator(RSS_LINK)).toHaveCount(1)
})
}

test('RSS autodiscovery link is present exactly once on a blog post page', async ({
page,
}) => {
await page.goto('/blog/')
const firstPost = page.locator('a.post-card').first()
const href = await firstPost.getAttribute('href')
expect(href, 'expected at least one blog post link on /blog/').toBeTruthy()

await page.goto(href as string)
await expect(page.locator(RSS_LINK)).toHaveCount(1)
})
6 changes: 0 additions & 6 deletions tests/test.ts

This file was deleted.