@edgekits/astro-i18n 0.1.0 → 0.1.2
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.
- package/CHANGELOG.md +20 -1
- package/README.md +275 -12
- package/dist/types.d.ts +1 -1
- package/package.json +5 -4
- package/src/components/LanguageSwitcher.astro +3 -2
- package/src/types.ts +3 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,7 +4,26 @@ All notable changes to this package are documented here. The format follows
|
|
|
4
4
|
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and the package uses
|
|
5
5
|
[Semantic Versioning](https://semver.org/).
|
|
6
6
|
|
|
7
|
-
## 0.1.
|
|
7
|
+
## 0.1.2 — 2026-10-13
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- `package.json` is normalised (`bin` path without `./`, `repository.url` in the `git+https://….git` form), so `npm publish` prints no warnings.
|
|
12
|
+
- The build removes `dist/` before compiling, so a deleted source file can no longer ship as a stale `dist/*.js`.
|
|
13
|
+
|
|
14
|
+
## 0.1.1 — 2026-10-13
|
|
15
|
+
|
|
16
|
+
### Changed
|
|
17
|
+
|
|
18
|
+
- `countryCode` in `languages` is optional. `LanguageSwitcher` renders the `flag` component only for a locale that has one; the item then shows the name alone.
|
|
19
|
+
- The `astro-i18n` skill asks whether to show flags (each locale's `countryCode`, SVGs from the `flag-icons` package or the project's own) and moves the project's pages under `src/pages/[lang]/` during adoption.
|
|
20
|
+
|
|
21
|
+
### Added
|
|
22
|
+
|
|
23
|
+
- "Using the skill": a user guide for the `astro-i18n` skill, the same section in this README and in the plugin's.
|
|
24
|
+
- A `prepublishOnly` script that builds `dist/` before `npm publish`.
|
|
25
|
+
|
|
26
|
+
## 0.1.0 — 2026-10-12
|
|
8
27
|
|
|
9
28
|
### Added
|
|
10
29
|
|
package/README.md
CHANGED
|
@@ -73,18 +73,22 @@ export default defineI18nConfig({
|
|
|
73
73
|
})
|
|
74
74
|
```
|
|
75
75
|
|
|
76
|
-
| Field | Required | Default | Meaning
|
|
77
|
-
| -------------------------- | -------- | ------------ |
|
|
78
|
-
| `languages` | yes | | `{ [locale]: {
|
|
79
|
-
| `defaultLocale` | yes | | one of `languages`; its JSON files define the schema
|
|
80
|
-
| `cookie` | yes | | `{ name, maxAge }` (seconds) of the language cookie
|
|
81
|
-
| `keyPrefix` | yes | | KV keys are `<keyPrefix>:<namespace>:<locale>`
|
|
82
|
-
| `missingTranslationBanner` | yes | | enables `MissingTranslationBanner`
|
|
83
|
-
| `routing` | yes | | `'prefix'`
|
|
84
|
-
| `localesDir` | no | `'locales'` | where the CLI reads `<locale>/<namespace>.json`
|
|
85
|
-
| `generatedDir` | no | `'src/i18n'` | where the CLI writes `runtime-constants.ts` and `fallbacks.generated.ts`
|
|
86
|
-
| `countryToLocale` | no | none | geo-IP step of the locale fallback (see Reference)
|
|
87
|
-
| `markdownLocale` | no | none | the locale `.md` endpoints are served in (see Reference)
|
|
76
|
+
| Field | Required | Default | Meaning |
|
|
77
|
+
| -------------------------- | -------- | ------------ | -------------------------------------------------------------------------------------------------------- |
|
|
78
|
+
| `languages` | yes | | `{ [locale]: { name, countryCode? } }`; `countryCode` is optional: the code your flag component receives |
|
|
79
|
+
| `defaultLocale` | yes | | one of `languages`; its JSON files define the schema |
|
|
80
|
+
| `cookie` | yes | | `{ name, maxAge }` (seconds) of the language cookie |
|
|
81
|
+
| `keyPrefix` | yes | | KV keys are `<keyPrefix>:<namespace>:<locale>` |
|
|
82
|
+
| `missingTranslationBanner` | yes | | enables `MissingTranslationBanner` |
|
|
83
|
+
| `routing` | yes | | `'prefix'` |
|
|
84
|
+
| `localesDir` | no | `'locales'` | where the CLI reads `<locale>/<namespace>.json` |
|
|
85
|
+
| `generatedDir` | no | `'src/i18n'` | where the CLI writes `runtime-constants.ts` and `fallbacks.generated.ts` |
|
|
86
|
+
| `countryToLocale` | no | none | geo-IP step of the locale fallback (see Reference) |
|
|
87
|
+
| `markdownLocale` | no | none | the locale `.md` endpoints are served in (see Reference) |
|
|
88
|
+
|
|
89
|
+
Locale codes (the keys of `languages`) are lowercase everywhere: the config, the `locales/`
|
|
90
|
+
folders and the URLs (`pt-br`, not `pt-BR`). `toIetfTag()` from `./format` gives the IETF form
|
|
91
|
+
(`pt-BR`) where one is needed, such as `<html lang>` and hreflang.
|
|
88
92
|
|
|
89
93
|
The config is validated when it loads: an empty `languages`, a `defaultLocale` or
|
|
90
94
|
`markdownLocale` outside it, or a bad `countryToLocale` entry throws with a message naming the
|
|
@@ -379,6 +383,265 @@ language-switcher > div {
|
|
|
379
383
|
}
|
|
380
384
|
```
|
|
381
385
|
|
|
386
|
+
#### Flags
|
|
387
|
+
|
|
388
|
+
The package ships no flag images. To show flags in the switcher, pass your own Astro component
|
|
389
|
+
as `flag`: each item renders it as `<Flag code={countryCode} size={16} />` before the language
|
|
390
|
+
name. A locale without a `countryCode` gets the name alone, and so does every locale when you
|
|
391
|
+
pass no `flag`. A recipe that copies only the SVGs your locales use from the `flag-icons` npm
|
|
392
|
+
package is under [Flags in the switcher](#flags-in-the-switcher) in "Using the skill".
|
|
393
|
+
|
|
394
|
+
<!-- skill-guide:start -->
|
|
395
|
+
|
|
396
|
+
## Using the skill
|
|
397
|
+
|
|
398
|
+
`astro-i18n` is a free agent skill that sets up `@edgekits/astro-i18n` in your project and keeps
|
|
399
|
+
working with it afterwards. It runs in Claude Code as a plugin, and in Cursor, OpenCode or any other
|
|
400
|
+
coding agent that reads `SKILL.md`. Its source is in
|
|
401
|
+
[`plugins/astro-i18n`](https://github.com/EdgeKits/astro-i18n/tree/main/plugins/astro-i18n).
|
|
402
|
+
|
|
403
|
+
### What it does
|
|
404
|
+
|
|
405
|
+
The skill adopts `@edgekits/astro-i18n` in an existing Astro project that runs on Cloudflare
|
|
406
|
+
Workers through `@astrojs/cloudflare`. It asks the questions only you can answer, follows the
|
|
407
|
+
package README in order, and checks the result against a checklist. After the setup it handles
|
|
408
|
+
the follow-up work: new keys, locales and namespaces, production copy, localized forms and
|
|
409
|
+
multilingual SEO.
|
|
410
|
+
|
|
411
|
+
It does not create an Astro project, and it stops if the project has no Cloudflare adapter: the
|
|
412
|
+
package depends on Workers KV. It copies no engine code into your project; everything it writes
|
|
413
|
+
uses the package's exports.
|
|
414
|
+
|
|
415
|
+
What changes in your project during the setup:
|
|
416
|
+
|
|
417
|
+
- dependencies: `@edgekits/astro-i18n`, and `flag-icons` as a dev dependency if you want flags;
|
|
418
|
+
- `astro.config`: the `edgekitsI18n()` integration;
|
|
419
|
+
- `wrangler.jsonc`: a `TRANSLATIONS` KV binding;
|
|
420
|
+
- new files: `edgekits-i18n.config.ts`, `locales/<locale>/*.json`, the generated files, and a
|
|
421
|
+
`Flag.astro` with its SVGs;
|
|
422
|
+
- `src/pages/`: your pages move under `src/pages/[lang]/`;
|
|
423
|
+
- your base layout: `<html lang>` from the request's locale, hreflang tags, the language
|
|
424
|
+
switcher.
|
|
425
|
+
|
|
426
|
+
### Installing it
|
|
427
|
+
|
|
428
|
+
In Claude Code, add the EdgeKits marketplace once, then install the plugin:
|
|
429
|
+
|
|
430
|
+
```
|
|
431
|
+
/plugin marketplace add EdgeKits/skills
|
|
432
|
+
/plugin install astro-i18n@edgekits
|
|
433
|
+
```
|
|
434
|
+
|
|
435
|
+
That installs it for you, in every project. To set it up for everyone working on one
|
|
436
|
+
repository, run these in the repository and commit `.claude/settings.json`:
|
|
437
|
+
|
|
438
|
+
```sh
|
|
439
|
+
claude plugin marketplace add EdgeKits/skills --scope project
|
|
440
|
+
claude plugin install astro-i18n@edgekits --scope project
|
|
441
|
+
```
|
|
442
|
+
|
|
443
|
+
The first command declares the EdgeKits marketplace in `.claude/settings.json`; the second
|
|
444
|
+
turns the plugin on there, under `enabledPlugins` (`"astro-i18n@edgekits": true`). Claude Code
|
|
445
|
+
honours those entries for a teammate once they trust the folder, but it does not download the
|
|
446
|
+
plugin for them: each teammate runs the same `claude plugin install … --scope project` once.
|
|
447
|
+
|
|
448
|
+
Any other agent, with the [skills CLI](https://skills.sh):
|
|
449
|
+
|
|
450
|
+
```sh
|
|
451
|
+
npx skills add EdgeKits/astro-i18n --skill astro-i18n
|
|
452
|
+
```
|
|
453
|
+
|
|
454
|
+
### Prerequisites
|
|
455
|
+
|
|
456
|
+
- An Astro `^7.3` project with `output: 'server'` and the `@astrojs/cloudflare` adapter `^14.3`.
|
|
457
|
+
For a new site: `npm create astro@latest`, then `npx astro add cloudflare`, then set
|
|
458
|
+
`output: 'server'` in `astro.config`.
|
|
459
|
+
- wrangler `^4.125` installed in the project (`npm i -D wrangler`) and a `wrangler.jsonc`. The
|
|
460
|
+
package's CLI runs the project's own wrangler, never a global one.
|
|
461
|
+
- A Cloudflare account. Local development needs none until you create the real KV namespace.
|
|
462
|
+
- For `edgekits-i18n migrate` (pushing copy to production): the site on a proxied Cloudflare
|
|
463
|
+
zone (orange cloud), that zone's ID, and an API token with the Zone › Cache Purge permission.
|
|
464
|
+
|
|
465
|
+
### First run on a fresh site
|
|
466
|
+
|
|
467
|
+
#### What to say
|
|
468
|
+
|
|
469
|
+
Open the project in your agent and ask for the result you want, for example:
|
|
470
|
+
|
|
471
|
+
- "Add i18n to this site: English as the default, German and Brazilian Portuguese."
|
|
472
|
+
- "Make the site multilingual with en and es, and send visitors from Spain and Mexico to
|
|
473
|
+
Spanish."
|
|
474
|
+
- "Install @edgekits/astro-i18n and set it up."
|
|
475
|
+
|
|
476
|
+
#### The questions it asks
|
|
477
|
+
|
|
478
|
+
The skill asks before it writes any code, and waits for the answers:
|
|
479
|
+
|
|
480
|
+
| Question | Example answer |
|
|
481
|
+
| ---------------------------------------------------------------------------- | --------------------------------------------- |
|
|
482
|
+
| Which locales, and which is the default? | `en` (default), `de`, `pt-br` |
|
|
483
|
+
| Does the site serve markdown endpoints (`/blog/x.md`)? In which locale? | No (or: yes, `en`) |
|
|
484
|
+
| Should a visitor's country pick the locale when nothing else does? How? | `DE`, `AT`, `CH` → `de`; `BR` → `pt-br` |
|
|
485
|
+
| Middleware: registered by the integration (`auto`), or in your own sequence? | `auto` |
|
|
486
|
+
| Flags in the language switcher? | Yes: `en` → `us`, `de` → `de`, `pt-br` → `br` |
|
|
487
|
+
|
|
488
|
+
For flags, a regional locale takes its region (`pt-br` → `br`, `en-gb` → `gb`), and for a
|
|
489
|
+
language-only locale the skill proposes the obvious country (`en` → `us`) for you to confirm. It
|
|
490
|
+
shows the full list back before it writes the config. If you have no preference on any of
|
|
491
|
+
these, it uses the defaults: no geo table, no markdown locale, `auto` middleware, flags on.
|
|
492
|
+
|
|
493
|
+
#### What it creates
|
|
494
|
+
|
|
495
|
+
- `edgekits-i18n.config.ts` with your answers, and the integration in `astro.config`.
|
|
496
|
+
- `locales/<default>/common.json` and `messages.json` (the banner texts and form error codes),
|
|
497
|
+
and the same files for each other locale.
|
|
498
|
+
- The generated files, written by `npx edgekits-i18n seed`: `i18n-data.json`,
|
|
499
|
+
`src/i18n.generated.d.ts`, `src/i18n/runtime-constants.ts`, `src/i18n/fallbacks.generated.ts`.
|
|
500
|
+
Commit them.
|
|
501
|
+
- The route layout: `src/pages/about.astro` becomes `src/pages/[lang]/about.astro`, and so on.
|
|
502
|
+
The root `index.astro` moves too, since the middleware redirects `/` to `/<locale>/`.
|
|
503
|
+
Endpoints that are not localized (`robots.txt`, `sitemap.xml`, `/api/*`) and `public/` stay
|
|
504
|
+
where they are.
|
|
505
|
+
- `src/components/Flag.astro` and one SVG per flag in `src/assets/icons/flags/`, if you chose
|
|
506
|
+
flags (the recipe is below).
|
|
507
|
+
- A KV namespace on your Cloudflare account (`wrangler kv namespace create`). The skill asks
|
|
508
|
+
before it runs that command. Until then, local development works with a placeholder id of 32
|
|
509
|
+
hexadecimal characters, such as `00000000000000000000000000000000`: the CLI checks the id's
|
|
510
|
+
shape before it runs wrangler.
|
|
511
|
+
|
|
512
|
+
#### Flags in the switcher
|
|
513
|
+
|
|
514
|
+
The package ships no flag images; `LanguageSwitcher` takes your flag component as its `flag`
|
|
515
|
+
prop and passes it each locale's `countryCode`. The skill's recipe, which you can also follow by
|
|
516
|
+
hand:
|
|
517
|
+
|
|
518
|
+
1. `npm i -D flag-icons` (MIT).
|
|
519
|
+
2. Copy the SVG of each configured `countryCode`, and only those, into
|
|
520
|
+
`src/assets/icons/flags/`, and commit them:
|
|
521
|
+
|
|
522
|
+
```sh
|
|
523
|
+
mkdir -p src/assets/icons/flags
|
|
524
|
+
for code in us de br; do cp node_modules/flag-icons/flags/4x3/$code.svg src/assets/icons/flags/; done
|
|
525
|
+
```
|
|
526
|
+
|
|
527
|
+
3. Add `src/components/Flag.astro`:
|
|
528
|
+
|
|
529
|
+
```astro
|
|
530
|
+
---
|
|
531
|
+
import type { SvgComponent } from 'astro/types'
|
|
532
|
+
|
|
533
|
+
interface Props {
|
|
534
|
+
code: string
|
|
535
|
+
size?: number
|
|
536
|
+
}
|
|
537
|
+
const { code, size = 16 } = Astro.props
|
|
538
|
+
|
|
539
|
+
const flags = import.meta.glob<SvgComponent>('../assets/icons/flags/*.svg', { eager: true, import: 'default' })
|
|
540
|
+
const Svg = flags[`../assets/icons/flags/${code}.svg`]
|
|
541
|
+
---
|
|
542
|
+
|
|
543
|
+
{Svg && <Svg width={(size * 4) / 3} height={size} aria-hidden="true" />}
|
|
544
|
+
```
|
|
545
|
+
|
|
546
|
+
4. Pass it to the switcher: `<LanguageSwitcher flag={Flag} />`.
|
|
547
|
+
|
|
548
|
+
A locale without a `countryCode`, or without an SVG, shows its name alone. The flag belongs to
|
|
549
|
+
the `countryCode`, not the language, so `pt` and `pt-br` can show different flags.
|
|
550
|
+
|
|
551
|
+
#### How it checks the result
|
|
552
|
+
|
|
553
|
+
Before it reports back, the skill runs its adoption checklist: the config matches your answers
|
|
554
|
+
and every locale code is lowercase; `seed` writes the generated files and leaves
|
|
555
|
+
`.i18n-hashes.json` alone; `astro check` passes; under `astro dev`, `/` redirects to a locale,
|
|
556
|
+
each locale renders its own copy (or the default locale's, if it has no JSON yet), an unknown
|
|
557
|
+
first segment such as `/zz/` is prefixed rather than crashing, `<html lang>` reads `pt-BR` on a
|
|
558
|
+
`pt-br` page, hreflang tags cover every locale plus `x-default`, and the switcher changes the
|
|
559
|
+
URL and sets the language cookie. It also checks that no page is left at `src/pages/*.astro`
|
|
560
|
+
and that every `countryCode` has its SVG.
|
|
561
|
+
|
|
562
|
+
### Everyday work
|
|
563
|
+
|
|
564
|
+
Ask in plain words: "add a key for the footer note", "add French", "add a `pricing`
|
|
565
|
+
namespace", "change the hero title in production". What the skill does:
|
|
566
|
+
|
|
567
|
+
- **A key or a value.** It adds a new key to the default locale first, since the default
|
|
568
|
+
locale's JSON is the type schema, then to the other locales, and runs `npx edgekits-i18n
|
|
569
|
+
seed`. A key that exists only in another locale is not typed.
|
|
570
|
+
- **A locale.** It adds the locale to `languages` (and its SVG, with flags on), optionally
|
|
571
|
+
writes `locales/<new>/`, runs `seed` and restarts the dev server. A locale without JSON is
|
|
572
|
+
routable already: it shows the default locale's copy and the missing-translation banner.
|
|
573
|
+
- **A namespace.** It creates `locales/<default>/<namespace>.json` and the same file in each
|
|
574
|
+
other locale, runs `seed`, and fetches the namespace only on the pages that render it.
|
|
575
|
+
- **Production copy.** Edit the JSON, then: `seed` and check it locally; run the project's
|
|
576
|
+
checks (`astro check`, tests, build); `npx edgekits-i18n migrate`, which pushes to production
|
|
577
|
+
KV and purges only the changed namespaces; commit the JSON together with
|
|
578
|
+
`.i18n-hashes.json`. No redeploy is needed unless the config or code changed too.
|
|
579
|
+
|
|
580
|
+
`.i18n-hashes.json` records what production KV holds. Only a successful `migrate` writes it,
|
|
581
|
+
it is committed right after, and nothing else edits it. `migrate` refuses to run while that
|
|
582
|
+
file has uncommitted changes.
|
|
583
|
+
|
|
584
|
+
### Forms and SEO
|
|
585
|
+
|
|
586
|
+
**Forms.** Ask for "a localized contact form with name, email and message", or "localize this
|
|
587
|
+
form". The skill asks for the fields and their rules, where the form submits (an Astro Action
|
|
588
|
+
by default) and where it renders. What comes back: stable error codes (`INVALID_EMAIL`) with a
|
|
589
|
+
message for every code in every locale's `messages.json`; a server schema that emits the codes;
|
|
590
|
+
an Astro Action; and a `.astro` form with an inline script. The browser side uses no framework
|
|
591
|
+
and no zod: it validates with a small hand-written mirror of the server schema, so the form
|
|
592
|
+
works with a strict Content Security Policy and without JavaScript.
|
|
593
|
+
|
|
594
|
+
**SEO.** Ask for "hreflang tags", "a sitemap for every locale", "an RSS feed per locale",
|
|
595
|
+
"`llms.txt`" or "`robots.txt` that blocks staging". The skill writes them as your project's
|
|
596
|
+
code, using the package's locale constants and helpers: a `SeoHreflangs` component and
|
|
597
|
+
`<html lang>` in the base layout, `sitemap.xml`, `[lang]/rss.xml`, `llms.txt` and `robots.txt`
|
|
598
|
+
endpoints.
|
|
599
|
+
|
|
600
|
+
### Rules the agent follows
|
|
601
|
+
|
|
602
|
+
- Locale codes are lowercase everywhere: config keys, `locales/` folders, URLs (`pt-br`). Only
|
|
603
|
+
`toIetfTag()` produces `pt-BR`, for `<html lang>` and hreflang.
|
|
604
|
+
- Generated files (`*.generated.*`, `runtime-constants.ts`, `i18n-data.json`) come from the CLI
|
|
605
|
+
and are never edited by hand.
|
|
606
|
+
- `@edgekits/astro-i18n/runtime` and `/middleware` run only in workerd. Anything Node loads
|
|
607
|
+
(`astro.config`, `src/content.config.ts`, unit tests) uses the Node-safe `/config` and
|
|
608
|
+
`/format` entries instead.
|
|
609
|
+
- No engine code is copied into the project. If the package lacks something, the skill says so
|
|
610
|
+
rather than re-implementing it.
|
|
611
|
+
- Secrets (`.dev.vars`, `.env*`, API tokens) never enter git, and anything that touches your
|
|
612
|
+
Cloudflare account is asked first.
|
|
613
|
+
|
|
614
|
+
### Troubleshooting
|
|
615
|
+
|
|
616
|
+
- **Edited translations do not show under `astro dev`.** The local Cache API keeps the first
|
|
617
|
+
value it served. Put `I18N_CACHE=off` in `.dev.vars`, restart the dev server, run `seed`.
|
|
618
|
+
- **A new key is a type error.** It was added only to a non-default locale, or the CLI has not
|
|
619
|
+
run since. Add it to the default locale and run `seed` (or `bundle`); if the editor still
|
|
620
|
+
shows the error, restart its TypeScript server.
|
|
621
|
+
- **`Cannot find module 'cloudflare:workers'` in `tsc`.** Run `npx wrangler types`.
|
|
622
|
+
- **`migrate` refuses to run.** `.i18n-hashes.json` has uncommitted changes. If the last
|
|
623
|
+
`migrate` wrote it, commit it. If anything else changed it, discard the change with
|
|
624
|
+
`git checkout .i18n-hashes.json` and run `migrate` again. Never edit or delete it to get
|
|
625
|
+
past the check.
|
|
626
|
+
- **`migrate` updated KV but the site shows old copy.** The purge was skipped: the zone is not
|
|
627
|
+
proxied, or the zone ID or token is missing. Fix it and run `migrate` again; it retries the
|
|
628
|
+
same purge.
|
|
629
|
+
- **Windows.** Local KV (`seed`) can fail with "Network connection lost" or "internal error"
|
|
630
|
+
when the project sits in a deep folder: the local Workers runtime hits the path length
|
|
631
|
+
limit, so keep the project at a short path. Stopping `astro dev` can leave `workerd.exe`
|
|
632
|
+
running and holding `.wrangler/state`; end it before the next `seed`. In PowerShell, copy
|
|
633
|
+
the flags with
|
|
634
|
+
`foreach ($c in 'us','de','br') { Copy-Item node_modules/flag-icons/flags/4x3/$c.svg src/assets/icons/flags/ }`.
|
|
635
|
+
|
|
636
|
+
### Privacy
|
|
637
|
+
|
|
638
|
+
This plugin collects, stores and sends no data. It contains no code, no hooks and no MCP servers, only
|
|
639
|
+
instructions (`SKILL.md`, its reference pages and two starter translation files). The commands it asks your agent
|
|
640
|
+
to run (`npm install`, `wrangler`, the package's `edgekits-i18n` CLI) talk to npm and to your own Cloudflare account
|
|
641
|
+
under their own terms. EdgeKits runs no service behind this plugin.
|
|
642
|
+
|
|
643
|
+
<!-- skill-guide:end -->
|
|
644
|
+
|
|
382
645
|
## How it works
|
|
383
646
|
|
|
384
647
|
A request reaches the middleware, which settles the URL's locale (redirecting when there is
|
package/dist/types.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@edgekits/astro-i18n",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "Edge-native i18n for Astro on Cloudflare Workers: translations in Workers KV, a per-namespace edge cache invalidated by the Purge API, and typed keys.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"astro",
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"author": "Gary Stupak",
|
|
17
17
|
"repository": {
|
|
18
18
|
"type": "git",
|
|
19
|
-
"url": "https://github.com/EdgeKits/astro-i18n"
|
|
19
|
+
"url": "git+https://github.com/EdgeKits/astro-i18n.git"
|
|
20
20
|
},
|
|
21
21
|
"homepage": "https://github.com/EdgeKits/astro-i18n#readme",
|
|
22
22
|
"bugs": {
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"./package.json": "./package.json"
|
|
39
39
|
},
|
|
40
40
|
"bin": {
|
|
41
|
-
"edgekits-i18n": "
|
|
41
|
+
"edgekits-i18n": "dist/cli/index.js"
|
|
42
42
|
},
|
|
43
43
|
"files": [
|
|
44
44
|
"dist",
|
|
@@ -51,7 +51,8 @@
|
|
|
51
51
|
"access": "public"
|
|
52
52
|
},
|
|
53
53
|
"scripts": {
|
|
54
|
-
"build": "tsc -p tsconfig.build.json",
|
|
54
|
+
"build": "node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\" && tsc -p tsconfig.build.json",
|
|
55
|
+
"prepublishOnly": "npm run build",
|
|
55
56
|
"test": "node --import ./test/register.mjs --test test/**/*.test.ts",
|
|
56
57
|
"typecheck": "tsc --noEmit",
|
|
57
58
|
"format": "prettier --write .",
|
|
@@ -5,7 +5,8 @@ import type { Locale } from '../constants'
|
|
|
5
5
|
|
|
6
6
|
interface Props {
|
|
7
7
|
// The project's flag component (an Astro component reference), passed in so the
|
|
8
|
-
// engine imports no project UI.
|
|
8
|
+
// engine imports no project UI. It receives the locale's `countryCode`; without the
|
|
9
|
+
// component, or for a locale without a `countryCode`, the item renders label-only.
|
|
9
10
|
flag?: (props: { code: string; size?: number }) => any
|
|
10
11
|
// The project's icons for the trigger button and the active item (Astro component
|
|
11
12
|
// references, like `flag`). Without them, the minimal inline defaults below render.
|
|
@@ -76,7 +77,7 @@ const { uiLocale: currentLang } = Astro.locals
|
|
|
76
77
|
disabled={isActive}
|
|
77
78
|
>
|
|
78
79
|
<span class={classes.itemLabel}>
|
|
79
|
-
{Flag && <Flag code={flagCode} size={16} />}
|
|
80
|
+
{Flag && flagCode && <Flag code={flagCode} size={16} />}
|
|
80
81
|
{label.name}
|
|
81
82
|
</span>
|
|
82
83
|
{isActive &&
|
package/src/types.ts
CHANGED
|
@@ -4,7 +4,9 @@
|
|
|
4
4
|
* under plain Node.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
// `countryCode` is what the switcher's `flag` component receives; without it the item
|
|
8
|
+
// shows the name alone.
|
|
9
|
+
export type I18nLanguage = { countryCode?: string; name: string }
|
|
8
10
|
|
|
9
11
|
export type I18nConfig = {
|
|
10
12
|
// The only source of truth for languages: the keys are the locales.
|