Dashboard Customization
Lunaria provides several ways to customize your localization dashboard to better fit your project’s look and feel. Follow this guide to understand all the available customization options.
Title and description
By default, Lunaria will add a default title and description for your dashboard. You can change it to make it easy to identify and find your project’s dashboard through search engines.
-
Add the
dashboard.title
option to your Lunaria config. The defined title will also be shown in the dashboard’s heading:lunaria.config.json {"dashboard": {"title": "Lunaria Localization Status"}} -
Add the
dashboard.description
option to your Lunaria config:lunaria.config.json {"dashboard": {"title": "Lunaria Localization Status","description": "Localization status dashboard for the Lunaria project."}}
Canonical URL
If you desire to publicize different versions of your dashboard (e.g. localized versions of the dashboard itself), it might be helpful to set a canonical URL to optimize your dashboard’s ranking on search engines.
To add a canonical URL, you can set dashboard.site
in your Lunaria configuration file:
{ "dashboard": { "site": "https://localization.lunaria.dev/" }}
Favicons
Setting a favicon can help match your project’s feel and make it easier to identify your dashboard in the user’s web browser. Lunaria allows you to define both multiple external and one inline favicon.
To add a favicon, you have to set dashboard.favicon
in your Lunaria configuration, with one of, or both the external
or inline
properties.
External favicons
External favicons are favicons you load through another URL as a resource. You can add them in the external
property of dashboard.favicon
. The example below adds both .svg
and .ico
favicons.
{ "dashboard": { "favicon": { "external": [ { "link": "https://lunaria.dev/favicon.svg", "type": "image/svg+xml" }, { "link": "https://lunaria.dev/favicon.ico", "type": "image/x-icon" }, ] } }}
Inline favicon
An inline favicon is a local .svg
favicon appended to your dashboard through a Data URI. You can add one through the inline
property of dashboard.favicon
.
-
Add your favicon SVG file to a directory in your project (e.g.
src/assets/
):Directorysrc/
Directoryassets/
- favicon.svg
- lunaria.config.json
-
Add the path to your favicon as the
inline
property ofdashboard.favicon
in your Lunaria config:lunaria.config.json {"dashboard": {"favicon": {"inline": "./src/assets/favicon.svg"}}}
Hidden path bases
The dashboard contains several paths as links to your source and localized content. These can be quite lengthy depending on how far they are from your project’s root directory. For example, if the unique part of your content files’ paths starts only after src/content/docs/
, you might want to hide this portion of the path and only show what’s relevant, e.g. guides/my-content.mdx
.
To do so, you can set the dashboard.basesToHide
option in your Lunaria config with all the desired path bases to hide. This example assumes you’re tracking content files that start at src/content/docs/
or src/i18n/
:
{ "dashboard": { "basesToHide": ["src/content/docs/", "src/i18n/"] }}
With this, references to paths like src/content/docs/guide.mdx
and src/i18n/dictionary.ts
will be shortened to their unique parts, namely guide.mdx
and dictionary.ts
.
Custom CSS
The dashboard can be further customized by adding your own custom CSS, allowing you to modify or extend the default styles provided by Lunaria out of the box.
-
Add a CSS file to a directory in your project (e.g.
src/styles/
). For example, you can change the default body font family used:src/styles/lunaria.css :root {--ln-font-body: Tahoma, sans-serif;} -
Add the path to your CSS file to your Lunaria config’s
dashboard.customCss
array property:lunaria.config.json {"dashboard": {"customCss": ["./src/styles/lunaria.css"]}}
Custom labels and language
By default, Lunaria’s dashboard comes with UI labels written in English. These UI labels can be completely changed, be it simple text labels, language values, or dynamic sentences (e.g. “X done, X outdated, X missing”).
Text labels
For example, you can change the default message shown when a locale’s localization is 100% complete by changing the statusByLocale.completeLocalization
property of dashboard.ui
:
{ "dashboard": { "ui": { "statusByLocale.completeLocalization": "No missing or outdated changes found, congratulations!" } }}
Format labels
Some labels, suffixed with Format
in their name, come with named {}
blocks that are going to be dynamically replaced with values from other UI labels or from the internal context, for example:
"statusByLocale.detailsTitleFormat": "{locale_name} ({locale_tag})",
These can also be changed, though it is highly recommended to not remove any of the {}
blocks present by default, as that would mean possibly not inserting a dynamic value that was expected.
For example, you could modify your dashboard to show the language details’ summary from the format Deutsch (de)
to Deutsch - de
by making a small change in the default statusByLocale.detailsTitleFormat
value:
{ "dashboard": { "ui": { "statusByLocale.detailsTitleFormat": "{locale_name} - {locale_tag}", } }}
lang
and dir
Since all labels can be changed, there is no imposition from completely translating the dashboard to another language. To make this even easier, dashboard.ui
exposes the lang
and dir
properties, which directly translates to the HTML lang
and dir
attributes used in your dashboard.
For example, that’s how you could go about changing your dashboard’s language to Brazilian Portuguese (most properties have been omitted from this example for simplicity’s sake):
{ "dashboard": { "ui": { "lang": "pt-BR", "statusByFile.heading": "Estado da localização por arquivo", "statusByFile.tableRowFile": "Arquivo", } }}
Custom UI elements
Lunaria’s dashboard was designed to be flexible and easily customizable through custom CSS and the available configuration options. When that’s not enough, Lunaria allows you to extend and override your dashboard’s UI using its Renderer API.
-
Add a new
renderer.config.ts
orrenderer.config.js
file to your project with the following content:renderer.config.ts import { defineRendererConfig } from '@lunariajs/core';export default defineRendererConfig({// options will go here...}); -
Add the path to your renderer file to your Lunaria config’s
renderer
configuration property:lunaria.config.json {"renderer": "./renderer.config.ts"}
Custom components
All UI elements in Lunaria are built without the use of frameworks, using only the good ol’ HTML. To improve the authoring experience, Lunaria comes with a built-in html
tagged template to help you build your own components.
A component in Lunaria is a function that receives a few parameters and returns a string of HTML:
import { html } from '@lunariajs/core';
const CustomParagraph = () => html`<p>This is my custom paragraph component!</p>`;
Since these components are template literals, you can interpolate values using the ${}
notation as you normally would in JavaScript:
import { html } from '@lunariajs/core';
const favoriteColor = "red";
const ColorComponent = () => html`<p>My favorite color is ${favoriteColor}!</p>`.
See the resulting HTML
<p>My favorite color is red!</p>
You can also interpolate over lists of values (e.g. arrays) using the .map()
method:
import { html } from '@lunariajs/core';
const catColors = ["grey", "white", "black", "orange", "buff"];
const CatColorsList = () => html`<ul>${catColors.map((catColor) => html`<li>${catColor}</li>`)}</ul>`
See the resulting HTML
<ul> <li>grey</li> <li>white</li> <li>black</li> <li>orange</li> <li>buff</li></ul>
Slotting elements
Elements can be slotted into the dashboard with the renderer’s slots
property. All components will be passed a copy of your Lunaria configuration you can use to get values from:
-
Create a new component using the
html
tagged template. In this case, a"robots"
meta tag with the"noindex"
content to avoid indexing the dashboard in search engines:renderer.config.ts import { defineRendererConfig, html } from '@lunariajs/core';const NoIndex = () => html`<meta name="robots" content="noindex" />`;export default defineRendererConfig({}); -
Add the created component to one of the available slots in the
slots
property. Here, thehead
slot will be used to insert the component into the dashboard’s<head>
element:renderer.config.ts import { defineRendererConfig, html } from '@lunariajs/core';const NoIndex = () => html`<meta name="robots" content="noindex" />`;export default defineRendererConfig({slots: {head: NoIndex,}});
Overriding elements
Elements can also be overridden in the dashboard with the renderer’s overrides
property. All components added to overrides
will be passed a copy of your Lunaria configuration, as well as the generated Lunaria status (except for the meta
property) you can use to get values from:
-
Create a new component using the
html
tagged template. In this case, the component will override the dashboard’s body and show thesharedPath
for each localized content:renderer.config.ts import { defineRendererConfig, html } from '@lunariajs/core';const NewBody = (config, status) => html`<ul>${status.map((s) => html`<li>${s.sharedPath}</li>`)}</ul>`;export default defineRendererConfig({}); -
Add the created component to one of the available overrides in the
overrides
property. Here, thebody
slot will be used to insert the component and override everything inside the dashboard’s<body>
element:renderer.config.ts import { defineRendererConfig, html } from '@lunariajs/core';const NewBody = (config, status) => html`<ul>${status.map((s) => html`<li>${s.sharedPath}</li>`)}</ul>`;export default defineRendererConfig({overrides: {body: NewBody,}});