@astrojs/starlight 0.12.0 → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/CHANGELOG.md +89 -0
  2. package/components/Icons.ts +2 -0
  3. package/components/MarkdownContent.astro +2 -123
  4. package/components/Search.astro +3 -2
  5. package/components/SiteTitle.astro +2 -2
  6. package/index.ts +17 -1
  7. package/integrations/asides.ts +17 -14
  8. package/integrations/expressive-code/exports.ts +36 -0
  9. package/integrations/expressive-code/index.ts +156 -0
  10. package/integrations/expressive-code/themes/night-owl-dark.jsonc +1796 -0
  11. package/integrations/expressive-code/themes/night-owl-light.jsonc +1695 -0
  12. package/integrations/expressive-code/theming.ts +108 -0
  13. package/integrations/expressive-code/translations.ts +26 -0
  14. package/integrations/shared/pathToLocale.ts +32 -0
  15. package/integrations/sitemap.ts +11 -7
  16. package/integrations/virtual-user-config.ts +14 -2
  17. package/package.json +6 -2
  18. package/schemas/expressiveCode.ts +13 -0
  19. package/schemas/i18n.ts +28 -2
  20. package/schemas/social.ts +2 -0
  21. package/style/markdown.css +115 -0
  22. package/translations/ar.json +5 -1
  23. package/translations/cs.json +5 -1
  24. package/translations/da.json +5 -1
  25. package/translations/de.json +5 -1
  26. package/translations/en.json +5 -1
  27. package/translations/es.json +5 -1
  28. package/translations/fa.json +5 -1
  29. package/translations/fr.json +5 -1
  30. package/translations/gl.json +5 -1
  31. package/translations/he.json +5 -1
  32. package/translations/hi.json +26 -0
  33. package/translations/id.json +5 -1
  34. package/translations/index.ts +4 -0
  35. package/translations/it.json +5 -1
  36. package/translations/ja.json +5 -1
  37. package/translations/ko.json +5 -1
  38. package/translations/nb.json +5 -1
  39. package/translations/nl.json +5 -1
  40. package/translations/pt.json +5 -1
  41. package/translations/ro.json +26 -0
  42. package/translations/ru.json +5 -1
  43. package/translations/sv.json +5 -1
  44. package/translations/tr.json +5 -1
  45. package/translations/uk.json +5 -1
  46. package/translations/vi.json +5 -1
  47. package/translations/zh-CN.json +5 -1
  48. package/utils/base.ts +4 -4
  49. package/utils/createPathFormatter.ts +57 -0
  50. package/utils/createTranslationSystem.ts +1 -1
  51. package/utils/format-path.ts +7 -0
  52. package/utils/navigation.ts +21 -10
  53. package/utils/path.ts +15 -0
  54. package/utils/route-data.ts +2 -2
  55. package/utils/user-config.ts +7 -0
  56. package/virtual.d.ts +9 -1
@@ -0,0 +1,108 @@
1
+ import fs from 'node:fs';
2
+ import { ExpressiveCodeTheme, type ThemeObjectOrShikiThemeName } from 'astro-expressive-code';
3
+
4
+ export type BundledThemeName = 'starlight-dark' | 'starlight-light';
5
+
6
+ export type ThemeObjectOrBundledThemeName = ThemeObjectOrShikiThemeName | BundledThemeName;
7
+
8
+ /**
9
+ * Converts the Starlight `themes` config option into a format understood by Expressive Code,
10
+ * loading any bundled themes and using the Starlight defaults if no themes were provided.
11
+ */
12
+ export function preprocessThemes(
13
+ themes: ThemeObjectOrBundledThemeName[] | undefined
14
+ ): ThemeObjectOrShikiThemeName[] {
15
+ // Try to gracefully handle cases where the user forgot to use an array in the config
16
+ themes = themes && !Array.isArray(themes) ? [themes] : themes;
17
+ // If no themes were provided, use our bundled default themes
18
+ if (!themes || !themes.length) themes = ['starlight-dark', 'starlight-light'];
19
+
20
+ return themes.map((theme) => {
21
+ // If the current entry is the name of a bundled theme, load it
22
+ if (theme === 'starlight-dark' || theme === 'starlight-light') {
23
+ const bundledThemeFile =
24
+ theme === 'starlight-dark' ? 'night-owl-dark.jsonc' : 'night-owl-light.jsonc';
25
+ return customizeBundledTheme(
26
+ ExpressiveCodeTheme.fromJSONString(
27
+ fs.readFileSync(new URL(`./themes/${bundledThemeFile}`, import.meta.url), 'utf-8')
28
+ )
29
+ );
30
+ }
31
+ // Otherwise, just pass it through
32
+ return theme;
33
+ });
34
+ }
35
+
36
+ /**
37
+ * Customizes some settings of the bundled theme to make it fit better with Starlight.
38
+ */
39
+ function customizeBundledTheme(theme: ExpressiveCodeTheme) {
40
+ theme.colors['titleBar.border'] = theme.colors['tab.activeBackground'];
41
+ theme.colors['editorGroupHeader.tabsBorder'] = theme.colors['tab.activeBackground'];
42
+
43
+ // Add underline font style to link syntax highlighting tokens
44
+ // to match the new GitHub theme link style
45
+ theme.settings.forEach((s) => {
46
+ if (s.name?.includes('Link')) s.settings.fontStyle = 'underline';
47
+ });
48
+
49
+ return theme;
50
+ }
51
+
52
+ /**
53
+ * Modifies the given theme by applying Starlight's CSS variables to the colors of UI elements
54
+ * (backgrounds, buttons, shadows etc.). This ensures that code blocks match the site's theme.
55
+ */
56
+ export function applyStarlightUiThemeColors(theme: ExpressiveCodeTheme) {
57
+ const isDark = theme.type === 'dark';
58
+ const neutralMinimal = isDark ? '#ffffff17' : '#0000001a';
59
+ const neutralDimmed = isDark ? '#ffffff40' : '#00000055';
60
+
61
+ // Make borders slightly transparent
62
+ const borderColor = 'color-mix(in srgb, var(--sl-color-gray-5), transparent 25%)';
63
+ theme.colors['titleBar.border'] = borderColor;
64
+ theme.colors['editorGroupHeader.tabsBorder'] = borderColor;
65
+
66
+ // Use the same color for terminal title bar background and editor tab bar background
67
+ const backgroundColor = isDark ? 'var(--sl-color-black)' : 'var(--sl-color-gray-6)';
68
+ theme.colors['titleBar.activeBackground'] = backgroundColor;
69
+ theme.colors['editorGroupHeader.tabsBackground'] = backgroundColor;
70
+
71
+ // Use the same color for terminal titles and tab titles
72
+ theme.colors['titleBar.activeForeground'] = 'var(--sl-color-text)';
73
+ theme.colors['tab.activeForeground'] = 'var(--sl-color-text)';
74
+
75
+ // Set tab border colors
76
+ const activeBorderColor = isDark ? 'var(--sl-color-accent-high)' : 'var(--sl-color-accent)';
77
+ theme.colors['tab.activeBorder'] = 'transparent';
78
+ theme.colors['tab.activeBorderTop'] = activeBorderColor;
79
+
80
+ // Use neutral colors for scrollbars
81
+ theme.colors['scrollbarSlider.background'] = neutralMinimal;
82
+ theme.colors['scrollbarSlider.hoverBackground'] = neutralDimmed;
83
+
84
+ // Set theme `bg` color property for contrast calculations
85
+ theme.bg = isDark ? '#23262f' : '#f6f7f9';
86
+ // Set actual background color to the appropriate Starlight CSS variable
87
+ const editorBackgroundColor = isDark ? 'var(--sl-color-gray-6)' : 'var(--sl-color-gray-7)';
88
+
89
+ theme.styleOverrides.frames = {
90
+ // Use the same color for editor background, terminal background and active tab background
91
+ editorBackground: editorBackgroundColor,
92
+ terminalBackground: editorBackgroundColor,
93
+ editorActiveTabBackground: editorBackgroundColor,
94
+ terminalTitlebarDotsForeground: borderColor,
95
+ terminalTitlebarDotsOpacity: '0.75',
96
+ inlineButtonForeground: 'var(--sl-color-text)',
97
+ frameBoxShadowCssValue: 'none',
98
+ };
99
+
100
+ // Use neutral, semi-transparent colors for default text markers
101
+ // to avoid conflicts with the user's chosen background color
102
+ theme.styleOverrides.textMarkers = {
103
+ markBackground: neutralMinimal,
104
+ markBorderColor: neutralDimmed,
105
+ };
106
+
107
+ return theme;
108
+ }
@@ -0,0 +1,26 @@
1
+ import { pluginFramesTexts } from 'astro-expressive-code';
2
+ import type { StarlightConfig } from '../../types';
3
+ import type { createTranslationSystemFromFs } from '../../utils/translations-fs';
4
+
5
+ export function addTranslations(
6
+ locales: StarlightConfig['locales'],
7
+ useTranslations: ReturnType<typeof createTranslationSystemFromFs>
8
+ ) {
9
+ for (const locale in locales) {
10
+ const lang = locales[locale]?.lang;
11
+ if (!lang) continue;
12
+
13
+ const t = useTranslations(locale);
14
+ const translationKeys = [
15
+ 'expressiveCode.copyButtonCopied',
16
+ 'expressiveCode.copyButtonTooltip',
17
+ 'expressiveCode.terminalWindowFallbackTitle',
18
+ ] as const;
19
+ translationKeys.forEach((key) => {
20
+ const translation = t(key);
21
+ if (!translation) return;
22
+ const ecId = key.replace(/^expressiveCode\./, '');
23
+ pluginFramesTexts.overrideTexts(lang, { [ecId]: translation });
24
+ });
25
+ }
26
+ }
@@ -0,0 +1,32 @@
1
+ import type { StarlightConfig } from '../../types';
2
+
3
+ function slugToLocale(
4
+ slug: string | undefined,
5
+ localesConfig: StarlightConfig['locales']
6
+ ): string | undefined {
7
+ const locales = Object.keys(localesConfig || {});
8
+ const baseSegment = slug?.split('/')[0];
9
+ return baseSegment && locales.includes(baseSegment) ? baseSegment : undefined;
10
+ }
11
+
12
+ /** Get current locale from the full file path. */
13
+ export function pathToLocale(
14
+ path: string | undefined,
15
+ {
16
+ starlightConfig,
17
+ astroConfig,
18
+ }: {
19
+ starlightConfig: { locales: StarlightConfig['locales'] };
20
+ astroConfig: { root: URL; srcDir: URL };
21
+ }
22
+ ): string | undefined {
23
+ const srcDir = new URL(astroConfig.srcDir, astroConfig.root);
24
+ const docsDir = new URL('content/docs/', srcDir);
25
+ const slug = path
26
+ // Format path to unix style path.
27
+ ?.replace(/\\/g, '/')
28
+ // Strip docs path leaving only content collection file ID.
29
+ // Example: /Users/houston/repo/src/content/docs/en/guide.md => en/guide.md
30
+ .replace(docsDir.pathname, '');
31
+ return slugToLocale(slug, starlightConfig.locales);
32
+ }
@@ -1,19 +1,23 @@
1
1
  import sitemap, { type SitemapOptions } from '@astrojs/sitemap';
2
2
  import type { StarlightConfig } from '../types';
3
3
 
4
- /**
5
- * A wrapped version of the `@astrojs/sitemap` integration configured based
6
- * on Starlight i18n config.
7
- */
8
- export function starlightSitemap(opts: StarlightConfig) {
4
+ export function getSitemapConfig(opts: StarlightConfig): SitemapOptions {
9
5
  const sitemapConfig: SitemapOptions = {};
10
6
  if (opts.isMultilingual) {
11
7
  sitemapConfig.i18n = {
12
- defaultLocale: opts.defaultLocale.locale! || 'root',
8
+ defaultLocale: opts.defaultLocale.locale || 'root',
13
9
  locales: Object.fromEntries(
14
10
  Object.entries(opts.locales).map(([locale, config]) => [locale, config?.lang!])
15
11
  ),
16
12
  };
17
13
  }
18
- return sitemap(sitemapConfig);
14
+ return sitemapConfig;
15
+ }
16
+
17
+ /**
18
+ * A wrapped version of the `@astrojs/sitemap` integration configured based
19
+ * on Starlight i18n config.
20
+ */
21
+ export function starlightSitemap(opts: StarlightConfig) {
22
+ return sitemap(getSitemapConfig(opts));
19
23
  }
@@ -10,7 +10,14 @@ function resolveVirtualModuleId<T extends string>(id: T): `\0${T}` {
10
10
  /** Vite plugin that exposes Starlight user config and project context via virtual modules. */
11
11
  export function vitePluginStarlightUserConfig(
12
12
  opts: StarlightConfig,
13
- { root, srcDir }: Pick<AstroConfig, 'root' | 'srcDir'>
13
+ {
14
+ build,
15
+ root,
16
+ srcDir,
17
+ trailingSlash,
18
+ }: Pick<AstroConfig, 'root' | 'srcDir' | 'trailingSlash'> & {
19
+ build: Pick<AstroConfig['build'], 'format'>;
20
+ }
14
21
  ): NonNullable<ViteUserConfig['plugins']>[number] {
15
22
  const resolveId = (id: string) =>
16
23
  JSON.stringify(id.startsWith('.') ? resolve(fileURLToPath(root), id) : id);
@@ -18,7 +25,12 @@ export function vitePluginStarlightUserConfig(
18
25
  /** Map of virtual module names to their code contents as strings. */
19
26
  const modules = {
20
27
  'virtual:starlight/user-config': `export default ${JSON.stringify(opts)}`,
21
- 'virtual:starlight/project-context': `export default ${JSON.stringify({ root, srcDir })}`,
28
+ 'virtual:starlight/project-context': `export default ${JSON.stringify({
29
+ build: { format: build.format },
30
+ root,
31
+ srcDir,
32
+ trailingSlash,
33
+ })}`,
22
34
  'virtual:starlight/user-css': opts.customCss.map((id) => `import ${resolveId(id)};`).join(''),
23
35
  'virtual:starlight/user-images': opts.logo
24
36
  ? 'src' in opts.logo
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@astrojs/starlight",
3
- "version": "0.12.0",
3
+ "version": "0.13.0",
4
4
  "description": "Build beautiful, high-performance documentation websites with Astro",
5
5
  "keywords": [
6
6
  "docs",
@@ -153,13 +153,16 @@
153
153
  "./props": "./props.ts",
154
154
  "./schema": "./schema.ts",
155
155
  "./types": "./types.ts",
156
+ "./expressive-code": "./integrations/expressive-code/exports.ts",
156
157
  "./index.astro": "./index.astro",
157
- "./404.astro": "./404.astro"
158
+ "./404.astro": "./404.astro",
159
+ "./style/markdown.css": "./style/markdown.css"
158
160
  },
159
161
  "peerDependencies": {
160
162
  "astro": "^3.2.0"
161
163
  },
162
164
  "devDependencies": {
165
+ "@astrojs/markdown-remark": "^3.2.1",
163
166
  "@types/node": "^18.16.19",
164
167
  "@vitest/coverage-v8": "^0.33.0",
165
168
  "astro": "^3.2.3",
@@ -170,6 +173,7 @@
170
173
  "@astrojs/sitemap": "^3.0.0",
171
174
  "@pagefind/default-ui": "^1.0.3",
172
175
  "@types/mdast": "^3.0.11",
176
+ "astro-expressive-code": "^0.29.0",
173
177
  "bcp-47": "^2.1.0",
174
178
  "execa": "^8.0.1",
175
179
  "hast-util-select": "^5.0.5",
@@ -0,0 +1,13 @@
1
+ import { z } from 'astro/zod';
2
+ import type { StarlightExpressiveCodeOptions } from '../integrations/expressive-code';
3
+
4
+ export const ExpressiveCodeSchema = () =>
5
+ z
6
+ .union([
7
+ z.custom<StarlightExpressiveCodeOptions>((value) => typeof value === 'object' && value),
8
+ z.boolean(),
9
+ ])
10
+ .describe(
11
+ 'Define how code blocks are rendered by passing options to Expressive Code, or disable the integration by passing `false`.'
12
+ )
13
+ .optional();
package/schemas/i18n.ts CHANGED
@@ -1,12 +1,16 @@
1
1
  import { z } from 'astro/zod';
2
2
 
3
3
  export function i18nSchema() {
4
- return starlightI18nSchema().merge(pagefindI18nSchema());
4
+ return starlightI18nSchema().merge(pagefindI18nSchema()).merge(expressiveCodeI18nSchema());
5
5
  }
6
6
  export type i18nSchemaOutput = z.output<ReturnType<typeof i18nSchema>>;
7
7
 
8
8
  export function builtinI18nSchema() {
9
- return starlightI18nSchema().required().strict().merge(pagefindI18nSchema());
9
+ return starlightI18nSchema()
10
+ .required()
11
+ .strict()
12
+ .merge(pagefindI18nSchema())
13
+ .merge(expressiveCodeI18nSchema());
10
14
  }
11
15
 
12
16
  function starlightI18nSchema() {
@@ -89,6 +93,10 @@ function starlightI18nSchema() {
89
93
  .describe('Label shown on the “next page” pagination arrow in the page footer.'),
90
94
 
91
95
  '404.text': z.string().describe('Text shown on Starlight’s default 404 page'),
96
+ 'aside.tip': z.string().describe('Text shown on the tip aside variant'),
97
+ 'aside.note': z.string().describe('Text shown on the note aside variant'),
98
+ 'aside.caution': z.string().describe('Text shown on the warning aside variant'),
99
+ 'aside.danger': z.string().describe('Text shown on the danger aside variant'),
92
100
  })
93
101
  .partial();
94
102
  }
@@ -158,3 +166,21 @@ function pagefindI18nSchema() {
158
166
  })
159
167
  .partial();
160
168
  }
169
+
170
+ function expressiveCodeI18nSchema() {
171
+ return z
172
+ .object({
173
+ 'expressiveCode.copyButtonCopied': z
174
+ .string()
175
+ .describe('Expressive Code UI translation. English default value: `"Copied!"`'),
176
+
177
+ 'expressiveCode.copyButtonTooltip': z
178
+ .string()
179
+ .describe('Expressive Code UI translation. English default value: `"Copy to clipboard"`'),
180
+
181
+ 'expressiveCode.terminalWindowFallbackTitle': z
182
+ .string()
183
+ .describe('Expressive Code UI translation. English default value: `"Terminal window"`'),
184
+ })
185
+ .partial();
186
+ }
package/schemas/social.ts CHANGED
@@ -24,6 +24,7 @@ export const socialLinks = [
24
24
  'email',
25
25
  'reddit',
26
26
  'patreon',
27
+ 'slack',
27
28
  ] as const;
28
29
 
29
30
  export const SocialLinksSchema = () =>
@@ -63,6 +64,7 @@ export const SocialLinksSchema = () =>
63
64
  email: 'Email',
64
65
  reddit: 'Reddit',
65
66
  patreon: 'Patreon',
67
+ slack: 'Slack',
66
68
  }[key];
67
69
  labelledLinks[key] = { label, url };
68
70
  }
@@ -0,0 +1,115 @@
1
+ .sl-markdown-content
2
+ :not(a, strong, em, del, span, input, code)
3
+ + :not(a, strong, em, del, span, input, code, :where(.not-content *)) {
4
+ margin-top: 1.5rem;
5
+ }
6
+
7
+ /* Headings after non-headings have more spacing. */
8
+ .sl-markdown-content
9
+ :not(h1, h2, h3, h4, h5, h6)
10
+ + :is(h1, h2, h3, h4, h5, h6):not(:where(.not-content *)) {
11
+ margin-top: 2.5rem;
12
+ }
13
+
14
+ .sl-markdown-content li + li:not(:where(.not-content *)),
15
+ .sl-markdown-content dt + dt:not(:where(.not-content *)),
16
+ .sl-markdown-content dt + dd:not(:where(.not-content *)),
17
+ .sl-markdown-content dd + dd:not(:where(.not-content *)) {
18
+ margin-top: 0.25rem;
19
+ }
20
+
21
+ .sl-markdown-content
22
+ li
23
+ > :last-child:not(li, ul, ol):not(a, strong, em, del, span, input, :where(.not-content *)) {
24
+ margin-bottom: 1.25rem;
25
+ }
26
+
27
+ .sl-markdown-content dt:not(:where(.not-content *)) {
28
+ font-weight: 700;
29
+ }
30
+ .sl-markdown-content dd:not(:where(.not-content *)) {
31
+ padding-inline-start: 1rem;
32
+ }
33
+
34
+ .sl-markdown-content :is(h1, h2, h3, h4, h5, h6):not(:where(.not-content *)) {
35
+ color: var(--sl-color-white);
36
+ line-height: var(--sl-line-height-headings);
37
+ font-weight: 600;
38
+ }
39
+
40
+ .sl-markdown-content :is(img, picture, video, canvas, svg, iframe):not(:where(.not-content *)) {
41
+ display: block;
42
+ max-width: 100%;
43
+ height: auto;
44
+ }
45
+
46
+ .sl-markdown-content h1:not(:where(.not-content *)) {
47
+ font-size: var(--sl-text-h1);
48
+ }
49
+ .sl-markdown-content h2:not(:where(.not-content *)) {
50
+ font-size: var(--sl-text-h2);
51
+ }
52
+ .sl-markdown-content h3:not(:where(.not-content *)) {
53
+ font-size: var(--sl-text-h3);
54
+ }
55
+ .sl-markdown-content h4:not(:where(.not-content *)) {
56
+ font-size: var(--sl-text-h4);
57
+ }
58
+ .sl-markdown-content h5:not(:where(.not-content *)) {
59
+ font-size: var(--sl-text-h5);
60
+ }
61
+ .sl-markdown-content h6:not(:where(.not-content *)) {
62
+ font-size: var(--sl-text-h6);
63
+ }
64
+
65
+ .sl-markdown-content a:not(:where(.not-content *)) {
66
+ color: var(--sl-color-text-accent);
67
+ }
68
+ .sl-markdown-content a:hover:not(:where(.not-content *)) {
69
+ color: var(--sl-color-white);
70
+ }
71
+
72
+ .sl-markdown-content code:not(:where(.not-content *)) {
73
+ background-color: var(--sl-color-bg-inline-code);
74
+ margin-block: -0.125rem;
75
+ padding: 0.125rem 0.375rem;
76
+ font-size: var(--sl-text-code-sm);
77
+ }
78
+ .sl-markdown-content :is(h1, h2, h3, h4, h5, h6) code {
79
+ font-size: inherit;
80
+ }
81
+
82
+ .sl-markdown-content pre:not(:where(.not-content *)) {
83
+ border: 1px solid var(--sl-color-gray-5);
84
+ padding: 0.75rem 1rem;
85
+ font-size: var(--sl-text-code);
86
+ tab-size: 2;
87
+ }
88
+
89
+ .sl-markdown-content pre code:not(:where(.not-content *)) {
90
+ all: unset;
91
+ font-family: var(--__sl-font-mono);
92
+ }
93
+
94
+ .sl-markdown-content blockquote:not(:where(.not-content *)) {
95
+ border-inline-start: 1px solid var(--sl-color-gray-5);
96
+ padding-inline-start: 1rem;
97
+ }
98
+
99
+ .sl-markdown-content table:not(:where(.not-content *)) {
100
+ display: block;
101
+ overflow: auto;
102
+ border-collapse: collapse;
103
+ }
104
+ .sl-markdown-content tr:nth-child(2n):not(:where(.not-content *)) {
105
+ background-color: var(--sl-color-gray-7, var(--sl-color-gray-6));
106
+ }
107
+ .sl-markdown-content :is(th, td):not(:where(.not-content *)) {
108
+ border: 1px solid var(--sl-color-hairline-light);
109
+ padding: 0.375rem 0.8125rem;
110
+ }
111
+
112
+ .sl-markdown-content hr:not(:where(.not-content *)) {
113
+ border: 0;
114
+ border-bottom: 1px solid var(--sl-color-hairline);
115
+ }
@@ -18,5 +18,9 @@
18
18
  "page.lastUpdated": "اخر تحديث:",
19
19
  "page.previousLink": "السابق",
20
20
  "page.nextLink": "التالي",
21
- "404.text": "الصفحة غير موجودة. تأكد من الرابط أو ابحث بإستعمال شريط البحث."
21
+ "404.text": "الصفحة غير موجودة. تأكد من الرابط أو ابحث بإستعمال شريط البحث.",
22
+ "aside.note": "ملحوظة",
23
+ "aside.tip": "نصيحة",
24
+ "aside.caution": "تنبيه",
25
+ "aside.danger": "تحذير"
22
26
  }
@@ -18,5 +18,9 @@
18
18
  "page.lastUpdated": "Poslední aktualizace:",
19
19
  "page.previousLink": "Předchozí",
20
20
  "page.nextLink": "Další",
21
- "404.text": "Stránka nenalezena. Zkontrolujte adresu URL nebo zkuste použít vyhledávací pole."
21
+ "404.text": "Stránka nenalezena. Zkontrolujte adresu URL nebo zkuste použít vyhledávací pole.",
22
+ "aside.note": "Note",
23
+ "aside.tip": "Tip",
24
+ "aside.caution": "Caution",
25
+ "aside.danger": "Danger"
22
26
  }
@@ -18,5 +18,9 @@
18
18
  "page.lastUpdated": "Sidst opdateret:",
19
19
  "page.previousLink": "Forrige",
20
20
  "page.nextLink": "Næste",
21
- "404.text": "Siden er ikke fundet. Tjek din URL eller prøv søgelinjen."
21
+ "404.text": "Siden er ikke fundet. Tjek din URL eller prøv søgelinjen.",
22
+ "aside.note": "Note",
23
+ "aside.tip": "Tip",
24
+ "aside.caution": "Caution",
25
+ "aside.danger": "Danger"
22
26
  }
@@ -18,5 +18,9 @@
18
18
  "page.lastUpdated": "Zuletzt bearbeitet:",
19
19
  "page.previousLink": "Vorherige Seite",
20
20
  "page.nextLink": "Nächste Seite",
21
- "404.text": "Seite nicht gefunden. Überprüfe die URL oder nutze die Suchleiste."
21
+ "404.text": "Seite nicht gefunden. Überprüfe die URL oder nutze die Suchleiste.",
22
+ "aside.note": "Hinweis",
23
+ "aside.tip": "Tipp",
24
+ "aside.caution": "Achtung",
25
+ "aside.danger": "Gefahr"
22
26
  }
@@ -18,5 +18,9 @@
18
18
  "page.lastUpdated": "Last updated:",
19
19
  "page.previousLink": "Previous",
20
20
  "page.nextLink": "Next",
21
- "404.text": "Page not found. Check the URL or try using the search bar."
21
+ "404.text": "Page not found. Check the URL or try using the search bar.",
22
+ "aside.note": "Note",
23
+ "aside.tip": "Tip",
24
+ "aside.caution": "Caution",
25
+ "aside.danger": "Danger"
22
26
  }
@@ -18,5 +18,9 @@
18
18
  "page.lastUpdated": "Última actualización:",
19
19
  "page.previousLink": "Página anterior",
20
20
  "page.nextLink": "Siguiente página",
21
- "404.text": "Página no encontrada. Verifica la URL o intenta usar la barra de búsqueda."
21
+ "404.text": "Página no encontrada. Verifica la URL o intenta usar la barra de búsqueda.",
22
+ "aside.note": "Nota",
23
+ "aside.tip": "Consejo",
24
+ "aside.caution": "Precaución",
25
+ "aside.danger": "Peligro"
22
26
  }
@@ -18,5 +18,9 @@
18
18
  "page.lastUpdated": "آخرین به روز رسانی:",
19
19
  "page.previousLink": "قبلی",
20
20
  "page.nextLink": "بعدی",
21
- "404.text": "صفحه یافت نشد. لطفاً URL را بررسی کنید یا از جستجو استفاده نمایید."
21
+ "404.text": "صفحه یافت نشد. لطفاً URL را بررسی کنید یا از جستجو استفاده نمایید.",
22
+ "aside.note": "Note",
23
+ "aside.tip": "Tip",
24
+ "aside.caution": "Caution",
25
+ "aside.danger": "Danger"
22
26
  }
@@ -18,5 +18,9 @@
18
18
  "page.lastUpdated": "Dernière mise à jour :",
19
19
  "page.previousLink": "Précédent",
20
20
  "page.nextLink": "Suivant",
21
- "404.text": "Page non trouvée. Vérifiez l’URL ou essayez d’utiliser la barre de recherche."
21
+ "404.text": "Page non trouvée. Vérifiez l’URL ou essayez d’utiliser la barre de recherche.",
22
+ "aside.note": "Note",
23
+ "aside.tip": "Astuce",
24
+ "aside.caution": "Attention",
25
+ "aside.danger": "Danger"
22
26
  }
@@ -18,5 +18,9 @@
18
18
  "page.lastUpdated": "Última actualización:",
19
19
  "page.previousLink": "Anterior",
20
20
  "page.nextLink": "Seguinte",
21
- "404.text": "Paxina non atopada. Comproba a URL ou intenta usar a barra de busca."
21
+ "404.text": "Paxina non atopada. Comproba a URL ou intenta usar a barra de busca.",
22
+ "aside.note": "Note",
23
+ "aside.tip": "Tip",
24
+ "aside.caution": "Caution",
25
+ "aside.danger": "Danger"
22
26
  }
@@ -18,5 +18,9 @@
18
18
  "page.lastUpdated": "עדכון אחרון:",
19
19
  "page.previousLink": "הקודם",
20
20
  "page.nextLink": "הבא",
21
- "404.text": "הדף לא נמצא. אנא בדקו את כתובת האתר או נסו להשתמש בסרגל החיפוש."
21
+ "404.text": "הדף לא נמצא. אנא בדקו את כתובת האתר או נסו להשתמש בסרגל החיפוש.",
22
+ "aside.note": "Note",
23
+ "aside.tip": "Tip",
24
+ "aside.caution": "Caution",
25
+ "aside.danger": "Danger"
22
26
  }
@@ -0,0 +1,26 @@
1
+ {
2
+ "skipLink.label": "इसे छोड़कर कंटेंट पर जाएं",
3
+ "search.label": "खोजें",
4
+ "search.shortcutLabel": "(खोजने के लिए / दबाएँ)",
5
+ "search.cancelLabel": "रद्द करे",
6
+ "search.devWarning": "खोज केवल उत्पादन बिल्ड में उपलब्ध है। \nस्थानीय स्तर पर परीक्षण करने के लिए साइट बनाए और उसका पूर्वावलोकन करने का प्रयास करें।",
7
+ "themeSelect.accessibleLabel": "थीम चुनें",
8
+ "themeSelect.dark": "अँधेरा",
9
+ "themeSelect.light": "रोशनी",
10
+ "themeSelect.auto": "स्वत",
11
+ "languageSelect.accessibleLabel": "भाषा चुने",
12
+ "menuButton.accessibleLabel": "मेन्यू",
13
+ "sidebarNav.accessibleLabel": "मुख्य",
14
+ "tableOfContents.onThisPage": "इस पृष्ठ पर",
15
+ "tableOfContents.overview": "अवलोकन",
16
+ "i18n.untranslatedContent": "यह कंटेंट अभी तक आपकी भाषा में उपलब्ध नहीं है.",
17
+ "page.editLink": "पृष्ठ संपादित करें",
18
+ "page.lastUpdated": "आखिरी अद्यतन:",
19
+ "page.previousLink": "पिछला",
20
+ "page.nextLink": "अगला",
21
+ "404.text": "यह पृष्ठ नहीं मिला। URL जांचें या खोज बार का उपयोग करने का प्रयास करें।",
22
+ "aside.note": "टिप्पणी",
23
+ "aside.tip": "संकेत",
24
+ "aside.caution": "सावधानी",
25
+ "aside.danger": "खतरा"
26
+ }
@@ -18,5 +18,9 @@
18
18
  "page.lastUpdated": "Terakhir diperbaharui:",
19
19
  "page.previousLink": "Sebelumnya",
20
20
  "page.nextLink": "Selanjutnya",
21
- "404.text": "Halaman tidak ditemukan. Cek kembali kolom URL atau gunakan fitur pencarian."
21
+ "404.text": "Halaman tidak ditemukan. Cek kembali kolom URL atau gunakan fitur pencarian.",
22
+ "aside.note": "Catatan",
23
+ "aside.tip": "Tips",
24
+ "aside.caution": "Perhatian",
25
+ "aside.danger": "Bahaya"
22
26
  }
@@ -19,9 +19,11 @@ import nb from './nb.json';
19
19
  import zh from './zh-CN.json';
20
20
  import ko from './ko.json';
21
21
  import sv from './sv.json';
22
+ import ro from './ro.json';
22
23
  import ru from './ru.json';
23
24
  import vi from './vi.json';
24
25
  import uk from './uk.json';
26
+ import hi from './hi.json';
25
27
 
26
28
  const { parse } = builtinI18nSchema();
27
29
 
@@ -47,8 +49,10 @@ export default Object.fromEntries(
47
49
  zh,
48
50
  ko,
49
51
  sv,
52
+ ro,
50
53
  ru,
51
54
  vi,
52
55
  uk,
56
+ hi,
53
57
  }).map(([key, dict]) => [key, parse(dict)])
54
58
  );
@@ -18,5 +18,9 @@
18
18
  "page.lastUpdated": "Ultimo aggiornamento:",
19
19
  "page.previousLink": "Indietro",
20
20
  "page.nextLink": "Avanti",
21
- "404.text": "Pagina non trovata. Verifica l'URL o prova a utilizzare la barra di ricerca."
21
+ "404.text": "Pagina non trovata. Verifica l'URL o prova a utilizzare la barra di ricerca.",
22
+ "aside.note": "Nota",
23
+ "aside.tip": "Consiglio",
24
+ "aside.caution": "Attenzione",
25
+ "aside.danger": "Pericolo"
22
26
  }