Create Next.js Page
Checklist
[ ] 1. src/app/[locale]/{route}/page.tsx (Server Component)
[ ] 2. Client wrapper in features/ or components/ (*Client.tsx or *View.tsx)
[ ] 3. generateMetadata for SEO
[ ] 4. setRequestLocale(locale) in server page
[ ] 5. loading.tsx + *Skeleton.tsx (optional)
[ ] 6. Use @/i18n/navigation for links
Server Page Template
// app/[locale]/about/page.tsx
import { setRequestLocale, getTranslations } from 'next-intl/server';
import { AboutView } from '@/features/about/components/AboutView';
export async function generateMetadata({ params }) {
const { locale } = await params;
const t = await getTranslations({ locale, namespace: 'about' });
return { title: t('title'), description: t('description') };
}
export default async function AboutPage({ params }) {
const { locale } = await params;
setRequestLocale(locale);
return <AboutView />;
}
Client Wrapper
'use client';
import { useTranslations } from 'next-intl';
export function AboutView() {
const t = useTranslations('about');
return <div>{t('content')}</div>;
}
Data-Fetching Page (SSR/ISR)
export const revalidate = 300;
export default async function ProductPage({ params }) {
const { locale, productSlug } = await params;
setRequestLocale(locale);
const { data } = await getProductBySlug(productSlug); // lib/api/
if (!data?.product) notFound();
return <ProductClient product={data.product} locale={locale} />;
}
Route Groups
| Group | Example |
|---|---|
(home) |
Homepage |
(auth) |
sign-in, sign-up |
(shop) |
products, categories |
(legal) |
about, policies |
Parentheses = no URL segment.
Links
import { Link, useRouter } from '@/i18n/navigation';
// NOT from 'next/link' or 'next/navigation'
Page-Specific Components
Co-locate in app/[locale]/{route}/components/ only when page-specific. Reusable → components/ or features/.