Hacktoberfest 2026: le issue che i maintainer hanno segnato per ottobre, aperte e adatte ai principianti. Sfoglia le issue Hacktoberfest

Every page is marked lang="en", and with one root layout a page can't declare its own language

Aperta
#621 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 1 giorno

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
4/5
Tempo stimato
3-5 giorni
Idoneità per principianti
44/100
Tipo di issue
Funzionalità
Chiarezza
Specificata chiaramente
Stato di attività
Attiva
Stack tecnologico
next.js, react, typescript

Direzione di ricerca

Start with src/app/layout.tsx, the existing src/app/s/layout.tsx, and src/app/page-metadata.test.ts to map the current layouts and homepage share image behavior. Then check scripts/check-budgets.mjs, budgets.json, and the listed e2e and axe specs before moving routes. Done when the layout split preserves the specified URLs, metadata, static markers and budgets, and the listed checks pass.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

enhancement pipeline:proposed pipeline:ux

Needs your OK: this splits the app into three root layouts (no URL changes) and gives unmatched URLs a styled 404 page. Everything else looks the same. Swap pipeline:proposed for pipeline:ready to have it built.

What happens

src/app/layout.tsx is the only root layout, and it hard-codes <html lang="en">. A Swedish signup's page has to say lang="sv" (WCAG 3.1.1, level A): screen readers pick their voice from it, and browsers use it to offer translation. A root layout can't see a page's params, so with one root layout the only way to know a signup's language would be to read request headers there. That turns every page dynamic, including the force-static help and legal pages.

Fix, in outline

  • Three root layouts. Route groups don't change URLs.
    • src/app/(site)/layout.tsx for /, /help/**, /privacy, /terms and /cookies, with lang="en".
    • src/app/(organizer)/layout.tsx for /app/**, /login/** and /oauth/**, with lang="en" for now. A later step in #619 makes it the organizer's language.
    • src/app/s/[slug]/layout.tsx for the participant pages, with lang="en" for now. A later step makes it the signup's. It absorbs src/app/s/layout.tsx, which only adds the footer.
  • src/app/root-shell.tsx: what every root layout shares. That's metadata (metadataBase, title template, description, openGraph, twitter), viewport (theme colour), the font variable, globals.css, and the <html> attributes, including suppressHydrationWarning.
  • Unmatched URLs: turn on experimental.globalNotFound (Next 15.4 and later) with src/app/global-not-found.tsx, prerendered, lang="en". Without it, Next's built-in 404 has no lang, which axe fails. If the flag ever goes away, a (site)/[...missing]/page.tsx that calls notFound() does the same job.
  • Icons, manifest.ts, robots.ts, sitemap.ts and the share images stay in src/app/.

Watch for

  • The home page's share image. Next attaches src/app/opengraph-image.png and twitter-image.png to the page beside them, and / sets openGraph without images. Moved into (site)/, / would lose its link preview card. Give / explicit images (SHARE_IMAGE in src/lib/seo.ts, as pageMetadata does for other pages) and drop the / exemption in src/app/page-metadata.test.ts.
  • Static stays static. /help, /help/[slug] and the legal pages must still show ○ in the build output.
  • Budgets. scripts/check-budgets.mjs strips route groups, so the budgets.json keys still match, and the table must not change.
  • Moving between root layouts is a full page load (/app → /help). That's expected.
  • Known and unchanged: in Next 15.5, a notFound() from a dynamic page sends an error shell (<html id="__next_error__">) and the browser then renders the not-found page. It's the same today.
  • This was spiked on Next 15.5.27 in Chromium with all three layouts. Segment not-found pages, the global 404 and a static /help all worked.

Choices this makes

  • Three root layouts, rather than reading headers in one. Default: three. It keeps help and legal static.
  • A styled global 404. Default: on, through globalNotFound. It's experimental; the catch-all page is the fallback.

Done when

  • / still has its share image, and its exemption in page-metadata.test.ts is gone.
  • The build output's static and dynamic markers are unchanged.
  • Icons and the manifest still load on /app and on a signup page.
  • pnpm budgets is unchanged.
  • e2e and axe specs pass, including tests/e2e/signup-not-found.spec.ts and a new check that an unmatched URL gets the styled 404 with lang.
  • pnpm lint && pnpm typecheck && pnpm knip && pnpm test and pnpm test:e2e pass.

Planned with the owner in https://claude.ai/code/session_01EFKmj716ZY3b3SwR8TV8Y2 and checked against the code on main at 35288fa. The full plan is private to the owner's account: https://claude.ai/artifact/VgQH6U2s2EVx3LX991fJi8 (a Claude session on that account can open it with the Artifact tool's read action). This is step 0.2 there.

Lingua principale
TypeScript
Stelle
19
Fork
4
Merge medio
22h 10m
PR unite (30g)
168

Preparare l'ambiente

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di richshaw/OpenSignup

Tutte le issue di richshaw/OpenSignup

Issue simili

Altre issue su TypeScript

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.