content icon indicating copy to clipboard operation
content copied to clipboard

Support i18n inline translations

Open JonathanXDR opened this issue 4 months ago • 6 comments

Is your feature request related to a problem? Please describe

Currently, when using Nuxt Content together with Nuxt i18n, inline translations inside content files (Markdown, YAML, JSON, CSV) are not supported. This means developers need to create a separate file for each locale (e.g., content/{locale}/team/jane-doe.yml), which works in cases where every property requires a different translation, but otherwise becomes redundant and creates unnecessary overhead.

This lack of support prevents content authors from keeping multilingual content in a single file with inline i18n keys. Without a built-in solution, teams are forced to manually extend collection schemas and implement workarounds.

Describe the solution you'd like

I would like Nuxt Content to support inline i18n statements natively across all formats (Markdown, YAML, JSON, CSV).

  • Developers should be able to write translations directly inside the same file using an i18n section.
  • The module should automatically detect those i18n keys and adjust the collection schema to merge translated props into the result of queryCollection.
  • If a top-level property exists alongside translations, it should serve as a fallback value if the translation for the current locale is missing.
  • The solution should be compatible with server-side locale detection (as provided by Nuxt i18n’s defineI18nLocaleDetector) so that translations can be resolved fully on the server side per request. This would allow developers to return localized content directly from the server without requiring any client-side adjustments.

This way, developers can adopt a clean and consistent multilingual content standard with zero configuration or effort on their side, while retaining the option for full server-side translation flows if their project requires it.

Describe alternatives you've considered

  • Separate locale-based files: e.g., content/de/team/jane-doe.yml and content/en/team/jane-doe.yml.

    • Works but is tedious and breaks content maintainability, especially with large datasets.
  • Manual schema adjustments: Extend the collection schema to process inline i18n keys manually.

    • Adds complexity and requires developers to duplicate logic that could be handled automatically by the module.

Both approaches are less efficient and more error-prone compared to built-in inline i18n support.

Additional context

Example content file (jane-doe.yml):

name: Jane Doe
icon: { name: lucide:user }
info:
  age: 25
  # If this top-level prop is defined even tho there are translations, it will be used as fallback description if the translation is missing
  country: Switzerland

# Same fallback approach here as above since the top-level prop is defined
description: Jane likes to read and travel.

i18n:
  de:
    description: Jane mag es zu lesen und zu reisen.
    # The props here will be merged with the top-level props
    info:
      country: Schweiz
  en:
    description: Jane likes to read and travel.
    info:
      country: Switzerland
  it:
    description: Jane ama leggere e viaggiare.
    info:
      country: Svizzera
  fr:
    description: Jane aime lire et voyager.
    info:
      country: Suisse

Expected generated output when using queryCollection (current locale = en):

[
  {
    "id": "team/team/jane-doe.yml",
    "title": "Jane Doe",
    "description": "Jane likes to read and travel.",
    "extension": "yml",
    "icon": {
      "name": "lucide:user"
    },
    "info": {
      "age": 25,
      "country": "Switzerland"
    },
    "meta": {
      "path": "/team/jane-doe",
      "body": {
        "name": "Jane Doe",
        "icon": {
          "name": "lucide:user"
        },
        "info": {
          "age": 25,
          "country": "Switzerland"
        },
        "description": "Jane likes to read and travel."
      }
    },
    "name": "Jane Doe",
    "stem": "team/jane-doe",
    "__hash__": "MoyLlRB-472Xv4vA9p5BpRd1VP-wL8u0N62lnKwhQ4Q"
  }
]

👉 This feature would make multilingual content authoring in Nuxt Content much more intuitive and would standardize inline i18n usage without requiring custom schemas or multiple file structures. With server-side locale detection and translation, developers could even serve localized content directly from the server on a per-request basis, aligning seamlessly with Nuxt i18n’s experimental server-side translation support.

JonathanXDR avatar Aug 19 '25 15:08 JonathanXDR

Hi, I appreciate your views about this important topic for Nuxt Content ! However my opinion is a bit different as I'm defending for a separation of content by language.

Your suggestion is making content on a same file, it's a good option for small content but I think it could lead to big file when content is huge with many language.

Nuxt Content 🤝 Nuxt Studio

My idea suggests to have work more closely to Nuxt Studio which will become open-source: by a native option, we could consider a main language which defines content basis (frontmatter, data and rich content) and for all the language nuxt content should support, Nuxt Studio should provide an easy way for creating them along the main language schema, and why not making it smoother using some AI (with a BYOK system).

Every change of a main language content would impact other language and for any content creation/update or deletion, Nuxt Studio could alert to update others languages content, as is it done with Linkedin when you update your profile, but here for all the language we're supporting.

Translation helper

As a Vue.js translator of the french version, the real nightmare is to be synced with the main content. For a complete translation from english to another, the only clue to know if a content is correctly translated —beyond verifying the accuracy of the translation itself— is git lines addition/deletion. If the addition equals deletion and number of line unchanged, structure of content is preserved, otherwise, something changed. This could be an helper for Nuxt Studio to detect translation de-synchronization.

What do you think?

I don't know if you are using Nuxt Studio, but I know from some leaks that Nuxt Studio will be more transparent to use (https://x.com/Atinux/status/1973877014848548926) This is for me a game changer, especially if translation helper is done properly. No more needed to work on IDE for content edition.

edimitchel avatar Oct 06 '25 22:10 edimitchel

Thanks a lot for your thoughtful response. I completely see where you’re coming from now! I actually think both our approaches could complement each other quite well then.

I agree that Nuxt Studio will be a game-changer for your problem here. Its integration could make the entire translation workflow much smoother and more intuitive. It's totally fair that it should become the central place for managing multi-language content for large projects.

That said, I still believe inline i18n support at the content level would add strong value, even in combination with your proposed Nuxt Studio workflow. For small to medium content or structured data files (like YAML or JSON), inline translations help keep things unified and easy to maintain without cluttering the content directory. For larger text-heavy content, your approach with Nuxt Studio managing separate localized files would make much more sense, especially with automatic sync alerts and translation helpers.

In the best case, Nuxt Studio would act as the central hub that bridges both approaches, exposing inline i18n sections directly in its UI for smaller content types, or managing per-locale files for larger documents while still reading from the same unified schema. That way, developers and content authors get the best of both worlds, and it becomes a matter of project size and workflow preference, not a hard limitation.

JonathanXDR avatar Oct 07 '25 08:10 JonathanXDR

I totally understand your point !

I think Nuxt Studio will be integrated inside Nuxt Content, with a separated system which will be self-hostable. So yes, Nuxt Studio could handle both type of internationalization, configurable from content.config.ts i guess.

It could be great to work on a more technical result of this discussion to help @farnabaz and @larbish.

@clemcode, I remember our discussion about Nuxt docs translation, this could be a great opportunity to ease the documentation translation process. But that's said, I don't know if documentation is still necessary to be translated with AI models which consumes llms.txt + MCP.

edimitchel avatar Oct 07 '25 11:10 edimitchel

I am just migrating our website from a big headless CMS to Nuxt Content because I just found out they not just require 100 € monthly to support more than two locales, but additionally 20 € per extra locale. Here are my two cents:

  • Take a look at the "big players" how they do it from a UI perspective, e.g. in no particular order: Contentful, Storyblok, Sanity, Directus, Strapi
  • The admin creates content types once (Nuxt Content: collections) -> In Nuxt Content the collections currently need to be duplicated. If having 20 languages one needs to define the exact same collections with same schemas 20 times -> duplicate code.
  • Fields/Blocks in a content type can be marked as translatable -> I would suggest to set default to true
  • In the admin UI (Nuxt Content: Studio), one can create content in the default language and has a language switcher on each content page.
  • When not editing the default language, each translatable field shows the text of the default language for help with translation
  • Some (most?) UI's also have integration with translators like DeepL or Google Translate, so adding a translation for a field may only be one click
  • If a translation is missing for a specific field, it falls back to the default language
  • Another important thing are translatable slugs. They differ from language to language but when viewing a single page we need to get all slugs for each locale to create the language switcher with Nuxt i18n https://i18n.nuxtjs.org/docs/compiler-macros/define-i18n-route as well as important seo meta tags set by Nuxt Seo.
  • The idea of @edimitchel is crucial: We need to have a main language (already defined by nuxt/i18!) and if the content changes, an alert can be displayed. This would be incredibly helpful.
  • The "killer feature" for me would be: Let an external tool, like DeepL, translate my whole website. Either once on build (but then it needs to be aware/smart and not translate what has already been translated and did not change), OR on demand when viewing a certain page in a certain language (and then cache the result).

What I dont know, because we didnt had the case, is how to handle having different content for different locales. E.g. if a page shouldnt be shown in a specific language or if one page has different content in a specific language.

Hoping this topic will be a high priority one @atinux @farnabaz

MickL avatar Oct 18 '25 10:10 MickL

After working with Nuxt Content for a bit, I had a few more points so I decided to open a new issue that is dedicated to i18n improvements in general and I tried to give better descriptions: #3579 Possibly upvote (as well as this issue) to give it more attention :)

A solution to what I wrote in #3579 could be exactly what was suggested here by @JonathanXDR : Define collections and md-files only once and then have inline translations next to each field. But also having one file per language (en/products.md, de/produkte.md, fr/produits, etc.) would be possible. I think technically inline translations would work better to support translatable slugs but for content editors separate files could be easier to work with.

MickL avatar Oct 20 '25 16:10 MickL

Hi there!

[...] For a complete translation from english to another, the only clue to know if a content is correctly translated —beyond verifying the accuracy of the translation itself— is git lines addition/deletion. If the addition equals deletion and number of line unchanged, structure of content is preserved, otherwise, something changed. This could be an helper for Nuxt Studio to detect translation de-synchronization.

This is not absolutely true. I can replace a key, the structure will be slightly the same, despite i18 being broken / incomplete.

@MickL a solution may be to add an "available in" selector when editing a page, with all available language enabled by default. Then, when editing the content (i.e, a paragraph block like with notion), the ui may display either automatic translation if none was provided, either the default locale (depending on config). In case of update, then related p block translations may be erased or at least marked as "to check".

kogratte avatar Nov 27 '25 09:11 kogratte