Skip to content

Languages and localization

Portfoliable supports multilingual portfolios from the start. The app is designed to work with localized titles, slugs, metadata, and case content while maintaining a clean default language experience.

Where localization lives

The generated app normally uses these files for language setup:

  • configs/i18n/i18n.config.js — locale list and metadata
  • configs/i18n/i18n.labels.js — translated UI labels
  • case markdown files — localized body content and case metadata
  • src/content/about/ABOUTME.md — localized About page content

You usually do not need to edit the locale plumbing by hand. The built-in commands are safer and more consistent.

Default behavior

Portfoliable works best when:

  • one locale is the default
  • other locales are added intentionally
  • each case has localized values for each supported language
  • language sections in markdown are explicit and complete

If a case is missing a locale value, the app may fall back to defaults or render incomplete output.

Add a locale

Use the CLI command:

bash
npm run add:language -- --code es --name Español --html-lang es-ES

You can also add a locale explicitly as LTR or RTL:

bash
npm run add:language -- --code ar --name العربية --html-lang ar-SA --rtl
npm run add:language -- --code it --name Italiano --html-lang it-IT --ltr

What this does:

  • adds the locale to the app config
  • updates the locale list used by the language switcher
  • syncs localized sections in About and case files
  • creates placeholder strings and localized blocks where needed

Remove a locale

bash
npm run delete:language -- --code es

If you remove the current default locale, use:

bash
npm run delete:language -- --code en --force

This prunes the locale from the synchronized content and updates the remaining defaults.

Sync localized content after manual edits

If you changed locale config by hand or want to ensure alignment across the app, run:

bash
npm run sync:locales

This is the reset button for localized structure. It helps keep the case metadata and About page consistent with the locale config.

Direction handling

Portfoliable derives the document direction from the configured locale data.

  • LTR locales are used for left-to-right languages such as English and Portuguese.
  • RTL locales are used for Arabic, Hebrew, Persian, and similar scripts.

Example:

bash
npm run add:language -- --code ar --name العربية --html-lang ar-SA --rtl

The app applies both lang and dir metadata automatically so the content and page structure match the selected language.

How to structure localized content

Your case markdown should include explicit language blocks, for example:

md
<!-- lang:en -->
## Problem
This is the English explanation.

<!-- lang:pt -->
## Problema
Esta é a explicação em português.

The same pattern is used for localized About content and metadata. Avoid mixing everything into one block unless you are intentionally building a single-language content file.

Locale edge cases

Missing translations

If you add a new locale but leave a case untranslated, the app may fall back to a default or render incomplete data.

Wrong htmlLang

The htmlLang value should match the real locale tag you want the browser to use. This affects language detection and page metadata.

Bad direction assumptions

Do not assume that a locale is always LTR. If you are using an RTL language, confirm that the app is rendering in the correct direction and that the text flow looks correct.

Locale-specific slugs

Use localized slugs intentionally. If a slug is changed in one locale, the route may no longer be stable for old links.

  1. add a locale with the CLI
  2. translate the generated content
  3. run npm run sync:locales if you edit locale files manually
  4. validate your case metadata
  5. preview the site in all locales you support

Example:

bash
npm run add:language -- --code es --name Español --html-lang es-ES
npm run sync:locales
npm run validate:content
npm run build

Next steps

Built with VitePress and Valence.