Configuration
Lunaria allows for extensive customization of its default behavior. This reference covers all the available options in a lunaria.config.mjs file.
import { defineConfig } from '@lunariajs/core/config';
export default defineConfig({ // your configuration options go here...});Top-level Options
Section titled “Top-level Options”repository (required)
Section titled “repository (required)”Type: Repository
Information about your project’s repository, used in the dashboard’s git hosting links. The expected properties are:
name— the unique name of your repository in the git hosting platform, e.g.'lunariajs/lunaria'.branch— the name of your repository’s branch tracked content, by default'main'.rootDir— the root directory of the project if using a monorepo, e.g.'docs'.hosting— the git hosting platform being used,'github'or'gitlab'.
export default defineConfig({ repository: { name: 'lunariajs/lunaria', branch: 'main', rootDir: 'docs', hosting: 'github', },});Repository
Section titled “Repository”type Repository = { name: string; branch?: string; rootDir?: string; hosting?: 'github' | 'gitlab';};sourceLocale (required)
Section titled “sourceLocale (required)”Type: Locale
The source locale of your project, where the source content is from.
label is the display name of the locale (e.g. 'English'), and lang is the BCP-47 tag, or other identifying code of the locale used in the tracked file’s path (e.g. 'en').
export default defineConfig({ sourceLocale: { label: 'English', lang: 'en', },});Optionally, parameters sets custom parameters with values specific to the locale that can be used in your files’ pattern.
export default defineConfig({ sourceLocale: { label: 'English', lang: 'en', parameters: { tag: 'en', }, },});Locale
Section titled “Locale”type Locale = { label: string; lang: string; parameters?: Record<string, string>;};locales (required)
Section titled “locales (required)”Type: Locale[]
The locales your project is localized into. Its entries follow the same signature as sourceLocale.
export default defineConfig({ locales: [ { label: 'Spanish', lang: 'es', }, { label: 'Português', lang: 'pt', }, ],});files (required)
Section titled “files (required)”Type: File[]
The files tracked by your dashboard.
The order of the entries in files will be respected and displayed accordingly in the dashboard. Each entry must have the following properties:
include— an array of glob patterns of the source file(s) to be tracked, e.g.['src/content/docs/en/**/*.mdx'].exclude— an array of glob patterns to be ignored from being tracked, defaults to['node_modules'].pattern— a path-to-regexp pattern of the file(s) paths, e.g.'src/content/docs/@lang/@path'(@langand@pathare custom syntax provided by Lunaria, in more complex cases can be changed for normal:langand:pathparameters). When the source and localized files follow different structures, an object with asourceand alocalespattern can be used instead, e.g.{ source: 'src/content/docs/@path', locales: 'src/content/docs/@lang/@path' }.
File types
Section titled “File types”Each entry in files has to include a type, changing how the tracking system works, the way the files are displayed in the dashboard, and adding new properties:
universal
Section titled “universal”The universal file type makes Lunaria track the file’s status by the git history alone, while also accepting any file extension.
export default defineConfig({ files: [ { include: ['en/**/*.md'], pattern: '@lang/@path', type: 'universal', }, ],});dictionary
Section titled “dictionary”The dictionary file type makes Lunaria check for key completion: each key in a source dictionary has to be present in the localizations to be marked as done.
The following file extensions are supported: json, yml, yaml, po, pot, js, cjs, mjs, ts, cts, mts.
If any keys are missing in localizations, the dashboard’s details for that locale will include a collapsible list of the missing keys for it to be considered done.
You can make keys optional (they don’t need to be included for a localization to be considered done) in the additional optionalKeys property. optionalKeys mirrors the structure of your dictionaries, where a key set to true is considered optional, including any keys nested inside of it.
export default defineConfig({ files: [ { include: ['ui/en/**/*.{json,yml}'], pattern: 'ui/@lang/@path', type: 'dictionary', optionalKeys: { footer: true, sidebar: { search: true, }, }, }, ],});You can also make the keys of a locale count towards the completion of another with the additional merge property. Each merge key is the lang of a locale with an array of the lang of the locales to merge keys from, in order. A key is only considered missing if it is absent from the locale and all the locales merged into it.
export default defineConfig({ files: [ { include: ['ui/en/**/*.{json,yml}'], pattern: 'ui/@lang/@path', type: 'dictionary', merge: { 'es-419': ['es'], }, }, ],});type File = { include: string[]; exclude?: string[]; pattern: string | { source: string; locales: string };} & ( | { type: 'universal' } | { type: 'dictionary'; optionalKeys?: OptionalKeys; merge?: Record<string, string[]> });
type OptionalKeys = { [key: string]: boolean | OptionalKeys };external
Section titled “external”Type: boolean
Default: false
Whether the tracked content is from an external repository. When enabled, Lunaria clones the repository set in repository into the cloneDir directory and tracks its content, instead of the current working directory’s.
This option is useful to build a dashboard for a repository from outside of it, e.g. from a different repository or project.
export default defineConfig({ external: true,});integrations
Section titled “integrations”Type: LunariaIntegration[]
Array of integrations to extend Lunaria with. An integration is an object with a name and hooks, where the setup hook runs before the configuration is validated and can update it through updateConfig().
export default defineConfig({ integrations: [ { name: 'my-integration', hooks: { setup: ({ config, updateConfig, logger }) => { logger.info(`Setting up ${config.repository.name}...`); updateConfig({ dashboard: { title: 'My Localization Status', }, }); }, }, }, ],});LunariaIntegration
Section titled “LunariaIntegration”type LunariaIntegration = { name: string; hooks: { setup?: (options: { config: LunariaUserConfig; updateConfig: (config: Partial<LunariaUserConfig>) => void; logger: ConsolaInstance; }) => void | Promise<void>; };};outDir
Section titled “outDir”Type: string
Default: './dist/lunaria'
The directory that lunaria build writes your final dashboard and status to.
The expected value is a relative path from the project’s root.
export default defineConfig({ outDir: './lunaria',});cacheDir
Section titled “cacheDir”Type: string
Default: './node_modules/.cache/lunaria'
The directory Lunaria uses to cache the git data of your tracked files between builds.
The expected value is a relative path from the project’s root.
export default defineConfig({ cacheDir: './lunaria/cache',});cloneDir
Section titled “cloneDir”Type: string
Default: './node_modules/.cache/lunaria/history'
The directory Lunaria uses to clone your external repository into.
The expected value is a relative path from the project’s root, different from cacheDir.
export default defineConfig({ cloneDir: './lunaria/history',});renderer
Section titled “renderer”Type: RendererConfig
The dashboard renderer configuration used to slot and override the dashboard’s content.
import { html } from '@lunariajs/core';
export default defineConfig({ renderer: { slots: { afterTitle: () => html`<p>Example component</p>`, }, },});Visit the Renderer API reference to learn about all the available options.
Tracking Options
Section titled “Tracking Options”tracking.ignoredKeywords
Section titled “tracking.ignoredKeywords”Type: string[]
Default: ['lunaria-ignore', 'fix typo']
Array of keywords in a commit’s title for Lunaria to automatically ignore and don’t trigger status changes. By default, any commits’ title including lunaria-ignore or fix typo will be ignored.
You can disable the feature by providing an empty array ([]), or override with your own keywords.
export default defineConfig({ tracking: { ignoredKeywords: ['i18nIgnore', 'en-only'], },});tracking.localizableProperty
Section titled “tracking.localizableProperty”Type: string
Name of a frontmatter property with boolean value determining if a file can be localized or not.
Any files where the property is absent or found with a false will not be tracked, while the ones with true will, and in case a file was found with a non-boolean value, it will not be tracked either.
For files that do not support frontmatter, this option will be ignored and the file assumed to be localizable.
This option is recommended when you use a file format that supports frontmatter metadata (e.g. Markdown, MDX, Markdoc) and you want to gradually make files available for localization. If you expect a specific file to never be localized, consider not tracking it in the first place.
export default defineConfig({ tracking: { localizableProperty: 'readyForL10n', },});Dashboard Options
Section titled “Dashboard Options”dashboard.title
Section titled “dashboard.title”Type: string
Default: 'Localization Status'
The title of your dashboard, used in the dashboard’s heading and meta tags.
export default defineConfig({ dashboard: { title: "My Project's Localization Status", },});dashboard.description
Section titled “dashboard.description”Type: string
Default: 'Online localization status dashboard of the project'
The description of your dashboard, used in the dashboard’s meta tags.
export default defineConfig({ dashboard: { description: 'The localization status dashboard of my project', },});dashboard.site
Section titled “dashboard.site”Type: string
The deployed URL of your dashboard, used in the dashboard’s meta tags.
export default defineConfig({ dashboard: { site: 'https://localization.lunaria.dev/', },});dashboard.basesToHide
Section titled “dashboard.basesToHide”Type: string[]
Array of path bases to be omitted from the generated dashboard’s links.
In contexts where the links to tracked files are deep in the directory structure, e.g. src/content/docs/file.mdx, it might be interesting to show more simplified link labels, e.g. file.mdx.
export default defineConfig({ dashboard: { basesToHide: ['src/content/docs/'], },});dashboard.customCss
Section titled “dashboard.customCss”Type: string[]
Array of relative paths to external .css files to inline into the dashboard.
export default defineConfig({ dashboard: { customCss: ['./lunaria/css/theme.css', './lunaria/css/custom.css'], },});dashboard.favicon
Section titled “dashboard.favicon”Type: Favicon
The favicon(s) of your generated dashboard.
external accepts an array of external favicons, with the following properties:
link— the URL of the external favicon, e.g.'https://lunaria.dev/favicon.svg'.type— the MIME type of the external resource, e.g.'image/svg+xml'.
inline accepts an relative path to a .svg file that will be inlined into the dashboard, e.g. './lunaria/favicon.svg'.
export default defineConfig({ dashboard: { favicon: { external: [ { link: 'https://lunaria.dev/favicon.svg', type: 'image/svg+xml', }, ], inline: './lunaria/favicon.svg', }, },});Favicon
Section titled “Favicon”type Favicon = { external?: { link: string; type: string }[]; inline?: string;};dashboard.ui
Section titled “dashboard.ui”Type: Record<string, string>
The UI strings of the dashboard. Specifically, the lang and dir keys refer to the HTML attributes of the same name used in the generated dashboard, while the other keys directly change the UI of the page.
The following code sample contains all the keys of dashboard.ui and its default values:
export default defineConfig({ dashboard: { ui: { dir: 'ltr', lang: 'en', 'status.emojiDone': '✔', 'status.emojiMissing': '❌', 'status.emojiOutdated': '🔄', 'status.done': 'done', 'status.missing': 'missing', 'status.outdated': 'outdated', 'statusByFile.heading': 'Localization status by file', 'statusByFile.tableRowFile': 'File', 'statusByFile.tableSummaryFormat': '{missing_emoji} {missing_word} {outdated_emoji} {outdated_word} {done_emoji} {done_word}', 'statusByLocale.completeLocalization': 'This localization is complete, amazing job! 🎉', 'statusByLocale.createFileLink': 'Create file', 'statusByLocale.detailsSummaryFormat': '{done_amount} {done_word}, {outdated_amount} {outdated_word}, {missing_amount} {missing_word}', 'statusByLocale.detailsTitleFormat': '{locale_name} ({locale_tag})', 'statusByLocale.heading': 'Localization progress by locale', 'statusByLocale.outdatedLocalizationLink': 'outdated localization', 'statusByLocale.sourceChangeHistoryLink': 'source change history', 'statusByLocale.incompleteLocalizationLink': 'incomplete localization', 'statusByLocale.missingKeys': 'Missing keys', }, },});A few UI string keys are suffixed with Format, these contain dynamically inserted text (sometimes from other UI strings) in curly braces, e.g. {locale_name}. You can change the order or omit these, depending on your needs.