feat: native i18n support for collections - #3753
Conversation
…ollectionLocales pages
|
This feature is really great and well needed for nuxt content! Thanks @JonathanXDR for the work. |
@narr07 Yes sure! |
|
@farnabaz could we please get your opinion/review on this? |
|
Any idea for dynamic slug with this pr? |
Dynamic slugs are not included in this PR, as mentioned in the description. Supporting them will likely require changes in both this repository and https://github.com/nuxt-modules/i18n. However, this would be worth exploring in a follow-up PR. |

🔗 Linked issue
❓ Type of change
📚 Description
Adds native i18n support to
@nuxt/content, so collections are defined once withi18n: trueand content files use an inlinei18nsection for translations. Only translated strings are specified, everything else is preserved from the default locale.queryCollectionautomatically detects the current locale from@nuxtjs/i18nand returns locale-resolved content with zero configuration.Features
i18n: trueauto-detects locales from@nuxtjs/i18n, or pass{ locales, defaultLocale }explicitlyi18nsection with per-locale overrides; arrays merged by index viadefuByIndex(preserves untranslated fields at every nesting level)queryCollectionreads the current locale from@nuxtjs/i18ntransparently (client:$i18n.locale, server:event.context.nuxtI18n); default locale uses single query, non-default uses two-query fallback mergeuseQueryCollectioncomposable: wrapsqueryCollection+useAsyncDatawith auto cache keys, locale-reactive re-fetching, and generic type overridequeryCollectionLocales: returns all locale variants for a content item (for language switchers and hreflang SEO).stem()convenience method: query data collections by filename without knowing the source directory prefix.locale()explicit override: manual locale control with optional fallback_i18nSourceHashfor detecting outdated translationsSecurity
assertSafeQueryrejects newlines (prevents multi-statement injection)COUNT()field names are quoted (prevents field injection)cleanupQuerystring parser rewritten with proper state machine (fixes triple-quote bypass)Known Limitations
en/products.mdvsde/produkte.md),queryCollectionLocalescannot link them because the stems differ. Same-filename content across locale directories works. This requires coordination with@nuxtjs/i18n(see nuxt-modules/i18n#3028).i18nsection, but there is no mechanism to hide a default-locale field for a specific locale.📝 Checklist
Tests
Documentation
useQueryCollectionandqueryCollectionLocalesutility docs.locale()and.stem()to query-collection API reference