Skip to content

Commit cb6a451

Browse files
committed
feat: documente configuration and change translations
1 parent 8b754f2 commit cb6a451

10 files changed

Lines changed: 526 additions & 115 deletions

File tree

Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
---
2+
title: Configuration
3+
description: Configure your Explainer project globally and per-app using @explainer/config.
4+
icon: settings
5+
order: 3
6+
---
7+
8+
# Configuration
9+
10+
Explainer uses a centralized configuration system via the `@explainer/config` package. It provides global defaults that can be overridden per-app.
11+
12+
## Package structure
13+
14+
```text
15+
packages/config/src/
16+
├── contracts.ts # TypeScript interfaces (SiteConfig, Sponsor, FooterLink, I18nMessages)
17+
├── config.ts # Default configuration values (single structure with i18n keys)
18+
├── i18n.ts # Translations keyed by locale (flat key-value pairs)
19+
├── utils.ts # Helper functions (defineConfig, formatTitle, t, resolveHref)
20+
└── index.ts # Public exports
21+
```
22+
23+
## Global configuration
24+
25+
The default configuration is defined in `packages/config/src/config.ts`. Translatable properties reference i18n keys instead of containing raw strings:
26+
27+
```ts
28+
import type { SiteConfig } from './contracts'
29+
30+
export const defaultConfig: SiteConfig = {
31+
name: 'Explainer',
32+
titleTemplate: '%s — Explainer',
33+
favicon: '/favicon.svg',
34+
logo: '/logo.svg',
35+
thumbnail: '/thumbnail.png',
36+
twitterCard: 'summary_large_image',
37+
ogType: 'website',
38+
github: 'https://github.com/LeadcodeDev/explainer_v2',
39+
sponsors: [/* ... */],
40+
defaultLocale: 'en',
41+
locales: ['en', 'fr'],
42+
footer: {
43+
description: 'footer.description', // i18n key
44+
columns: {
45+
documentation: 'footer.columns.documentation', // i18n key
46+
resources: 'footer.columns.resources',
47+
community: 'footer.columns.community',
48+
},
49+
copyright: 'footer.copyright',
50+
builtWith: 'footer.builtWith',
51+
links: {
52+
documentation: [
53+
{ label: 'footer.links.gettingStarted', href: '/{locale}/explainer/getting-started' },
54+
// ...
55+
],
56+
resources: [
57+
{ label: 'footer.links.github', href: 'https://github.com/...', external: true },
58+
{ label: 'footer.links.blog', href: '', appId: 'blog' },
59+
],
60+
community: [
61+
{ label: 'footer.links.issues', href: 'https://github.com/.../issues', external: true },
62+
],
63+
},
64+
},
65+
}
66+
```
67+
68+
Link `href` values support a `{locale}` placeholder that is resolved at render time.
69+
70+
## SiteConfig reference
71+
72+
| Property | Type | Description |
73+
|----------|------|-------------|
74+
| `name` | `string` | Project name displayed in navbar and footer |
75+
| `titleTemplate` | `string` | Page title template. Use `%s` as placeholder (e.g. `%s — Explainer`) |
76+
| `favicon` | `string` | Path to the favicon file |
77+
| `logo` | `string` | Path to the logo file (used in navbar) |
78+
| `thumbnail` | `string` | Default OG image path |
79+
| `twitterCard` | `'summary' \| 'summary_large_image'` | Twitter card type |
80+
| `ogType` | `string` | Open Graph type |
81+
| `github` | `string` | GitHub repository URL |
82+
| `sponsors` | `Sponsor[]` | List of sponsors |
83+
| `defaultLocale` | `string` | Default locale for translations |
84+
| `locales` | `string[]` | Supported locales |
85+
| `footer` | `object` | Footer configuration with i18n keys and links |
86+
87+
## Per-app override
88+
89+
Each app can override the global configuration using `defineConfig()` in its `src/config.ts`:
90+
91+
```ts [apps/docs/src/config.ts]
92+
import { defineConfig } from '@explainer/config'
93+
94+
export const siteConfig = defineConfig({
95+
titleTemplate: '%s — Explainer',
96+
})
97+
```
98+
99+
```ts [apps/blog/src/config.ts]
100+
import { defineConfig } from '@explainer/config'
101+
102+
export const siteConfig = defineConfig({
103+
titleTemplate: '%s — Blog',
104+
})
105+
```
106+
107+
`defineConfig()` deep-merges your overrides with the default configuration. You only need to specify the properties you want to change.
108+
109+
## Internationalization (i18n)
110+
111+
Translations are stored in `packages/config/src/i18n.ts` as flat key-value maps per locale:
112+
113+
```ts
114+
import type { I18nMessages } from './contracts'
115+
116+
export const i18n: Record<string, I18nMessages> = {
117+
en: {
118+
'description': 'Documentation boilerplate for developers.',
119+
'footer.description': 'A modern documentation framework...',
120+
'footer.columns.documentation': 'Documentation',
121+
'footer.columns.resources': 'Resources',
122+
'footer.columns.community': 'Community',
123+
'footer.copyright': '© {year} Explainer. All rights reserved.',
124+
'footer.builtWith': 'Built with {icon} using Astro',
125+
'footer.links.gettingStarted': 'Getting Started',
126+
// ...
127+
},
128+
fr: {
129+
'description': 'Boilerplate de documentation pour les développeurs.',
130+
'footer.description': 'Un framework de documentation moderne...',
131+
'footer.columns.documentation': 'Documentation',
132+
'footer.columns.resources': 'Ressources',
133+
'footer.columns.community': 'Communauté',
134+
'footer.copyright': '© {year} Explainer. Tous droits réservés.',
135+
'footer.builtWith': 'Construit avec {icon} grâce à Astro',
136+
'footer.links.gettingStarted': 'Premiers pas',
137+
// ...
138+
},
139+
}
140+
```
141+
142+
Supported placeholders: `{year}` (current year), `{icon}` (heart icon), `{locale}` (in hrefs).
143+
144+
### Using translations
145+
146+
Use `t()` to resolve an i18n key for a given locale:
147+
148+
```ts
149+
import { t } from '@explainer/config'
150+
151+
t('fr', 'footer.description')
152+
// "Un framework de documentation moderne..."
153+
```
154+
155+
Use `resolveHref()` to replace `{locale}` in URLs:
156+
157+
```ts
158+
import { resolveHref } from '@explainer/config'
159+
160+
resolveHref('/{locale}/explainer/getting-started', 'fr')
161+
// "/fr/explainer/getting-started"
162+
```
163+
164+
If the requested locale is not found, `t()` falls back to `defaultLocale`.
165+
166+
## Sponsors
167+
168+
Sponsors are defined globally in the configuration:
169+
170+
```ts
171+
sponsors: [
172+
{
173+
id: 'mineral',
174+
name: 'Mineral',
175+
href: 'https://mineral-dart.dev/',
176+
logoUrl: 'https://mineral-dart.dev/logo.svg',
177+
tier: 'silver', // 'gold' | 'silver' | 'bronze'
178+
},
179+
]
180+
```
181+
182+
Each sponsor has a `tier` property that determines its visual styling.
183+
184+
## Utility functions
185+
186+
| Function | Signature | Description |
187+
|----------|-----------|-------------|
188+
| `defineConfig` | `(overrides?) => SiteConfig` | Creates a config by deep-merging overrides with defaults |
189+
| `formatTitle` | `(config, pageTitle) => string` | Applies the title template to a page title |
190+
| `t` | `(locale, key) => string` | Resolves an i18n key for a given locale with fallback |
191+
| `resolveHref` | `(href, locale?) => string` | Replaces `{locale}` placeholder in URLs |
192+
| `getMessages` | `(locale?) => I18nMessages` | Returns the full message map for a locale |

apps/docs/src/content/docs/explainer/default/en/project-structure.mdx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ explainer-v2/
1616
│ ├── blog/ # Blog (Astro)
1717
│ └── website/ # Landing page (Astro)
1818
├── packages/
19+
│ ├── config/ # Global site configuration
1920
│ ├── ui/ # Shared React UI components
2021
│ ├── mdx/ # MDX components & remark plugins
2122
│ └── thumbnail/ # OG thumbnail generation
@@ -41,7 +42,8 @@ Each app is an independent Astro project that can be built and deployed separate
4142

4243
| Package | Name | Purpose | Used by |
4344
|---------|------|---------|---------|
44-
| `packages/ui` | `@explainer/ui` | Button, Card, Navbar, ThemeToggle, Dropdown, MobileMenu, LocaleSwitcher | All apps |
45+
| `packages/config` | `@explainer/config` | Global site configuration, sponsors, i18n, title templates | All apps |
46+
| `packages/ui` | `@explainer/ui` | Button, Card, Navbar, Footer, ThemeToggle, Dropdown, MobileMenu, LocaleSwitcher | All apps |
4547
| `packages/mdx` | `@explainer/mdx` | MDX component overrides, Callout, Steps, Tabs, CodeGroup, Preview, remark plugins, Shiki config | Docs, Blog |
4648
| `packages/thumbnail` | `@explainer/thumbnail` | OG image generation using Satori + Resvg | Docs, Blog, Website |
4749

0 commit comments

Comments
 (0)