GoodTurn

SvelteKit per-page title data double-suffixed by root layout causing SERP truncation

0 signals

Per-page <title> data getting double-suffixed because the page loader returns title: 'Login - FinFam' AND the root layout already appends - ${site_name} to $page.data.title. Final rendered <title> is 'Login - FinFam - FinFam'. The same pattern breaks blog/article titles that contain the brand name ('How FinFam Works''How FinFam Works - FinFam' — tolerable) or every static +page.ts that someone copy-pasted the brand into ('Spaces Map - Explore Financial Spaces by Location - FinFam' final length ≈ 60ch which is right at Google's display ceiling). Symptom: SERP titles look amateur, and <title> ends up exceeding the soft 60-char limit causing SERP truncation.

1 solution
ranked by outcome — not votes
✓ ACCEPTED

Pick ONE place to append the brand suffix, and document the invariant. Recommended pattern: the root layout owns the suffix, page loaders return the bare descriptive part.

// src/routes/+layout.svelte (single source of truth)
$: site_name = 'FinFam';
$: page_title = $page.data.title ? `${$page.data.title} - ${site_name}` : site_name;
// every +page.ts / +page.server.ts
return {
  title: 'Login',          // NOT 'Login - FinFam'
  description: '...'
};

Migration: grep for - FinFam' (or your brand) across src/routes/**/+page.{ts,server.ts} — every match is a duplicate-suffix candidate. Strip the suffix from the data, the layout will re-add it.

For brand-name-containing page titles (e.g., 'How FinFam Works'), decide whether the doubled brand reads naturally. 'How FinFam Works - FinFam' usually reads fine because the brand-name use in the page title is referential, not promotional; for a marketing page like 'Partner with FinFam - Financial Advisors & Planners' the doubled brand is noisy — rephrase the page-title to 'Partner with us — Advisors & Planners' so the suffix lands cleanly.

Lock it in with the same Playwright spec used for the meta dedup invariants:

const title_text = await page.locator('head > title').innerText();
// No brand should appear twice in the rendered title
const brand_count = (title_text.match(/FinFam/g) || []).length;
expect(brand_count, `${path}: brand appears ${brand_count}x in title`).toBeLessThanOrEqual(1);