Skip to content

feat(announcements): add SEO metadata via server layout.tsx#1300

Closed
mvanhorn wants to merge 1 commit intoMODSetter:mainfrom
mvanhorn:osc/1244-announcements-seo-metadata
Closed

feat(announcements): add SEO metadata via server layout.tsx#1300
mvanhorn wants to merge 1 commit intoMODSetter:mainfrom
mvanhorn:osc/1244-announcements-seo-metadata

Conversation

@mvanhorn
Copy link
Copy Markdown
Contributor

@mvanhorn mvanhorn commented Apr 24, 2026

Fixes #1244

What changed

/announcements is a public, crawlable route but its page.tsx is "use client", so it can't export metadata directly and was falling back to the root app/layout.tsx's generic title/description.

Adds a server-component surfsense_web/app/(home)/announcements/layout.tsx that exports route-specific metadata and passes children through. Same shape as the neighboring /blog, /changelog, /contact, /privacy, /terms routes.

Notes

  • Canonical URL matches app/layout.tsx's metadataBasehttps://surfsense.com/announcements (not .net as the issue example used).
  • page.tsx is unchanged.
  • The layout is a pure pass-through <>{children}</>, so existing behavior (auto-mark-read, layout.tsx in parent (home) group) is preserved.

High-level PR Summary

This PR adds SEO metadata to the /announcements route by introducing a server-component layout.tsx file. Since the existing page.tsx is a client component and cannot export metadata directly, this new layout provides route-specific title, description, canonical URL, OpenGraph tags, and Twitter card metadata while passing through children unchanged. This ensures search engines and social media platforms display proper metadata for the announcements page.

⏱️ Estimated Review Time: 5-15 minutes

💡 Review Order Suggestion
Order File Path
1 surfsense_web/app/(home)/announcements/layout.tsx

Need help? Join our Discord

Summary by CodeRabbit

  • New Features
    • New announcements section now available with comprehensive SEO metadata support. Includes canonical URL configuration, Open Graph meta tags, and Twitter Card tags for enhanced visibility across search engines and social media platforms. Ensures optimal content presentation when shared or discovered online.

The announcements page is a public, crawlable route but its page.tsx is
'use client', so it can't export metadata itself and falls back to the
root app/layout.tsx. Add a server-component layout.tsx under
app/(home)/announcements/ that exports route-specific metadata (title,
description, canonical, OpenGraph, Twitter) in the same shape as the
neighboring /blog, /changelog, /contact, /privacy, /terms routes.
page.tsx is unchanged.

Canonical URL matches app/layout.tsx's metadataBase
(https://surfsense.com).

Fixes MODSetter#1244
@vercel
Copy link
Copy Markdown

vercel Bot commented Apr 24, 2026

@mvanhorn is attempting to deploy a commit to the Rohan Verma's projects Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 24, 2026

📝 Walkthrough

Walkthrough

Adds a server-side layout component to surfsense_web/app/(home)/announcements/ that exports route-specific SEO metadata (title, description, canonical URL, Open Graph, and Twitter card tags) for the announcements page. The layout simply renders its children without additional logic.

Changes

Cohort / File(s) Summary
Announcements Route Layout
surfsense_web/app/(home)/announcements/layout.tsx
New server layout file exporting structured metadata for SEO (title, description, canonical, Open Graph, Twitter cards) and a default layout component that passes through children.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Suggested reviewers

  • MODSetter

Poem

🐰 Hops with glee down the SEO trail,
Metadata blooms where pages set sail,
No "use client" to break the spell,
Just Server Components serving up well!
Announcements now shine in search results bright,
Hop, hop, hooray—the metadata's right! 🌟

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: adding SEO metadata to the announcements route via a server layout component.
Linked Issues check ✅ Passed The PR implements all requirements from #1244: creates a server layout with route-specific metadata (title, description, canonical, OpenGraph, Twitter), exports no 'use client', and renders children unchanged.
Out of Scope Changes check ✅ Passed All changes are within scope of #1244; only the new layout.tsx file is added without modifications to page.tsx or other unrelated files.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (2)
surfsense_web/app/(home)/announcements/layout.tsx (2)

23-25: Nit: drop the fragment wrapper.

A layout that only renders children can return them directly; the <>…</> wrapper adds no value.

♻️ Proposed refactor
-export default function AnnouncementsLayout({ children }: { children: ReactNode }) {
-	return <>{children}</>;
-}
+export default function AnnouncementsLayout({ children }: { children: ReactNode }) {
+	return children;
+}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@surfsense_web/app/`(home)/announcements/layout.tsx around lines 23 - 25, The
AnnouncementsLayout function currently returns children wrapped in a React
fragment; remove the unnecessary fragment wrapper in the AnnouncementsLayout
component and return the children directly (i.e., have AnnouncementsLayout
return the children value instead of <>children</>) to simplify the render.

7-15: Consider relative URLs to leverage metadataBase.

The root app/layout.tsx sets metadataBase: new URL("https://surfsense.com"), which allows child routes to use relative paths (e.g. /announcements) for alternates.canonical and openGraph.url. Next.js will resolve them against metadataBase automatically, avoiding hardcoded domains in every route and making environment/domain changes a single-file edit.

Neighboring routes like /blog also currently hardcode absolute URLs, so adopting relative URLs here would improve on the existing pattern.

♻️ Proposed refactor
 	alternates: {
-		canonical: "https://surfsense.com/announcements",
+		canonical: "/announcements",
 	},
 	openGraph: {
 		title: "Announcements | SurfSense",
 		description: "Latest product updates, feature releases, and news from SurfSense.",
-		url: "https://surfsense.com/announcements",
+		url: "/announcements",
 		type: "website",
 	},
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@surfsense_web/app/`(home)/announcements/layout.tsx around lines 7 - 15,
Replace the hardcoded absolute URLs in this announcements route with relative
paths so Next.js resolves them against the root metadataBase; specifically
change alternates.canonical and openGraph.url in announcements layout.tsx from
"https://surfsense.com/announcements" to the relative path "/announcements"
(leave title/description/type unchanged) so environment/domain changes are
centralized in the root app/layout.tsx metadataBase.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@surfsense_web/app/`(home)/announcements/layout.tsx:
- Around line 23-25: The AnnouncementsLayout function currently returns children
wrapped in a React fragment; remove the unnecessary fragment wrapper in the
AnnouncementsLayout component and return the children directly (i.e., have
AnnouncementsLayout return the children value instead of <>children</>) to
simplify the render.
- Around line 7-15: Replace the hardcoded absolute URLs in this announcements
route with relative paths so Next.js resolves them against the root
metadataBase; specifically change alternates.canonical and openGraph.url in
announcements layout.tsx from "https://surfsense.com/announcements" to the
relative path "/announcements" (leave title/description/type unchanged) so
environment/domain changes are centralized in the root app/layout.tsx
metadataBase.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 287e473b-cc80-4c5b-bce5-169550bf9eef

📥 Commits

Reviewing files that changed from the base of the PR and between 16587ec and 1ad7560.

📒 Files selected for processing (1)
  • surfsense_web/app/(home)/announcements/layout.tsx

@MODSetter
Copy link
Copy Markdown
Owner

@mvanhorn Please raise PR's on dev branch

@mvanhorn
Copy link
Copy Markdown
Contributor Author

Got it, thanks for the pointer. Reopened against dev in #1303.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add SEO metadata for /announcements via a server layout.tsx

2 participants