Skip to content

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

@MODSetter

Description

@MODSetter

Description

surfsense_web/app/(home)/announcements/page.tsx is a public, crawlable page but has no SEO metadata of its own. The entire file is marked "use client", which prevents exporting metadata or generateMetadata from the same module (those only work in Server Components).

Current file (lines 1–18):

"use client";

import { useEffect } from "react";
import { AnnouncementCard } from "@/components/announcements/AnnouncementCard";
import { AnnouncementsEmptyState } from "@/components/announcements/AnnouncementsEmptyState";
import { useAnnouncements } from "@/hooks/use-announcements";

export default function AnnouncementsPage() {
    const { announcements, markAllRead } = useAnnouncements();
    useEffect(() => {
        markAllRead();
    }, [markAllRead]);
    // ...
}

So the route falls back to root app/layout.tsx metadata, giving generic titles/descriptions in search results and social previews.

Other marketing routes (e.g. /blog, /changelog, /contact, /privacy, /terms) already define metadata or generateMetadata; this is the gap.

What to do

Create a server layout at surfsense_web/app/(home)/announcements/layout.tsx that exports route-specific metadata and just renders its children:

import type { Metadata, ReactNode } from "next";

export const metadata: Metadata = {
    title: "Announcements | SurfSense",
    description: "Latest product updates, feature releases, and news from SurfSense.",
    alternates: {
        canonical: "https://www.surfsense.net/announcements",
    },
    openGraph: {
        title: "Announcements | SurfSense",
        description: "Latest product updates, feature releases, and news from SurfSense.",
        url: "https://www.surfsense.net/announcements",
        type: "website",
    },
    twitter: {
        card: "summary_large_image",
        title: "Announcements | SurfSense",
        description: "Latest product updates, feature releases, and news from SurfSense.",
    },
};

export default function AnnouncementsLayout({ children }: { children: ReactNode }) {
    return <>{children}</>;
}

Important:

  • Do NOT add "use client" to this layout — it must stay a Server Component so metadata export works
  • Do NOT change page.tsx
  • If the canonical domain differs (check app/layout.tsx for the actual metadataBase), adjust it

Verify

  • View the page source at /announcements and confirm the new <title> and <meta> tags are present
  • next build succeeds

Acceptance criteria

  • New app/(home)/announcements/layout.tsx exists with route-specific metadata
  • Existing page behavior is unchanged

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions