Support I18n with SEO Improvement
INFRASTRUCTURE •
Situation
Needed to expand target audiences, stop expecting readers to be able to read both Korean and English.
Task
- Configure i18n settings with
next-intlproperly - Utilize message system properly
- Provide metadata aligned with locale, SEO optimization
- Sitemap generation with language alternates
- Add translation layer for string contents in database
- Update
dbpackage and cache layer
Action
1. Configuration
- Specified
next-intli18n configuration to support full prefix-url translations (navigation,request,routing) - Migrated all pages under
[locale]directory - Enabled static parameters generation for locale prefix
- Excluded static assets from i18n through
proxy.ts
2. Message System
useTranslationsfor CSR pages/components,getTranslationsfor SSR pages/components.- Replaced custom formatting utilities with
useFormatter/getFormatter, configured inrequestfile.
3. Metadata i18n
- For static pages with no DB access, consolidated metadata information with message json files.
- For pages with DB access, separated the query by locale then generated metadata with localized data.
- Found duplicate logic during the implementation, extracted the logic into separate utility file at
utils/server/metadata.tswithserver-onlydeclaration. - Applied SEO best practices for localized metadata by providing
canonical URLs withx-defaultsupport.
4. Sitemap Generation
next-sitemaprequired manual update even for dynamic routes generated from DB, and also required additional CI configurations usingpost-buildscript.- Replaced sitemap generation by
next-sitemapwith Next.js defaultsitemap.ts, which naturally integrated with updated i18n configuration. - Now the sitemap is generated when the
/sitemap.xmlis requested dynamically.
5. Translation Layer in Database
- Added
localeenum(ko,en). - Created junction table having localized content.
- Updated database and prisma schema, also migrated contents.
- Excluded
titlecolumn, for coherent typography (Latin only)
6. Update Package and Cache layer
- Adjusted queries to match with database schema.
- Set default locale guard for both,
DEFAULT_LOCALEinconstants.tsfile for package,routing.defaultLocalefor cache layer. Maybe later, let db package to receive default locale from environment variables. - More granular cache control supported through
posts-localecache tags.
Result
The site now serves content in both Korean and English with proper SEO support. Adding new locales in the future only requires extending the locale enum and providing translated content.
One performance degradation noticed, that because of prefixed locale, the entire pages reloads when switching languages.