Files
Rocketmc/.github/instructions/i18n-convert.instructions.md
Calum H. d418eaee12 feat: create modal limit alerting (#4429)
* draft: layout for alert

* feat: simplify

* feat: remove dummy data

* fix: lint and widths

* feat: use chips rather than dropdown select

* feat: remove gap from admonition header v body

* Revert "feat: remove gap from admonition header v body"

This reverts commit 46cce52799bc3ac24825a73ca4add18e0acad3c1.

* fix: niche fixes

* feat: update for new backend structure

* fix: i18n
2025-09-28 19:48:21 +00:00

3.4 KiB
Raw Blame History

applyTo
applyTo
**/*.vue

You are given a Nuxt/Vue single-file component (.vue). Your task is to convert every hard-coded natural-language string in the into our localization system using @vintl/vintl-nuxt (which wraps FormatJS).

Please follow these rules precisely:

  1. Identify translatable strings
  • Scan the for all user-visible strings (inner text, alt attributes, placeholders, button labels, etc.). Do not extract dynamic expressions (like {{ user.name }}) or HTML tags. Only extract static human-readable text.
    1. Create message definitions
    • In the <script setup> block, import defineMessage or defineMessages from @vintl/vintl.
    • For each extracted string, define a message with a unique id (use a descriptive prefix based on the component path, e.g. auth.welcome.long-title) and a defaultMessage equal to the original English string. Example: const messages = defineMessages({ welcomeTitle: { id: 'auth.welcome.title', defaultMessage: 'Welcome' }, welcomeDescription: { id: 'auth.welcome.description', defaultMessage: 'Youre now part of the community…' }, })
    1. Handle variables and ICU formats
    • Replace dynamic parts with ICU placeholders: "Hello, ${user.name}!" → {name} and defaultMessage: 'Hello, {name}!'
    • For numbers/dates/times, use ICU/FormatJS options (e.g., currency): {price, number, ::currency/USD}
    • For plurals/selects, use ICU: '{count, plural, one {# message} other {# messages}}'
    1. Rich-text messages (links/markup)
    • In defaultMessage, wrap link/markup ranges with tags, e.g.: "By creating an account, you agree to our Terms and Privacy Policy."
    • Render rich-text messages with <IntlFormatted> from @vintl/vintl/components and map tags via values:
    • For simple emphasis: 'Welcome to <strong>Modrinth</strong>!' and map 'strong': (c) => <strong>{c}</strong>
    1. Formatting in templates
    • Import and use useVIntl(); prefer formatMessage for simple strings: const { formatMessage } = useVIntl() <button>{{ formatMessage(messages.welcomeTitle) }}</button>
    • Vue methods like $formatMessage, $formatNumber, $formatDate are also available if needed.
    1. Naming conventions and id stability
    • Make ids descriptive and stable (e.g., error.generic.default.title). Group related messages with defineMessages.
    1. Avoid Vue/ICU delimiter collisions
    • If an ICU placeholder would end right before }} in a Vue template, insert a space so it becomes } } to avoid parsing issues.
    1. Update imports and remove literals
    • Ensure imports for defineMessage/defineMessages, useVIntl, and <IntlFormatted> are present. Replace all hard-coded strings with formatMessage(...) or <IntlFormatted> and remove the literals.
    1. Preserve functionality
    • Do not change logic, layout, reactivity, or bindings—only refactor strings into i18n.

    Use existing patterns from our codebase:

    • Variables/plurals: see apps/frontend/src/pages/frog.vue
    • Rich-text link tags: see apps/frontend/src/pages/auth/welcome.vue and apps/frontend/src/error.vue

    When you finish, there should be no hard-coded English strings left in the template—everything comes from formatMessage or <IntlFormatted>.