2.29.0
Minor Changes
-
20c2ffe: Add the opt-in
devErrorResponseVite plugin option to return HTTP 500 while translation compilation or configuration is invalid, and resume serving after recovery.Wait for pending watch compilations when Vite closes, preventing writes after shutdown and interference with the next server in the same process.
Patch Changes
- da2ebab: Accept readonly URL inputs, including SvelteKit 3's
page.url, inlocalizeUrlanddeLocalizeUrl. URL-like inputs are normalized to native URLs so unmatched routes still return a mutableURL.
2.28.0
Minor Changes
-
17d1aed: Add
cookieSameSiteandcookieSecurecompiler options for the locale cookie thatsetLocale()writes. Both attributes are omitted by default, so the cookie only changes when you opt in.cookieSecure: "auto"addsSecureonly onhttps:pages, andcookieSameSite: "none"withoutcookieSecurethrows when Paraglide compiles the runtime, because browsers drop that cookie.The runtime exports
cookieSameSiteandcookieSecure, so server code that writes the same cookie withSet-Cookiecan reuse the policy. With"auto", the server has to resolve the protocol itself. -
b95a16b: Add
redirect: "navigation"toparaglideMiddlewarefor GET and HEAD clients that omitSec-Fetch-Destbut accept HTML. In this mode, form POST requests pass through to the resolve callback. The default"document"mode keeps its existing redirect behavior.The new mode adds
Varyfields when needed to keep cached redirects and resolved responses separate. Mutable callback responses are updated in place to preserve their identity and runtime-specific state, including precompressed bodies on Cloudflare Workers. Immutable responses are rebuilt using the original response as the constructor options. -
b375894: Add an optional ESLint/Oxlint plugin at
@inlang/paraglide-js/eslint. Enableparaglide/no-dynamic-message-accessto report runtime indexing, computed destructuring, and whole-catalog spread/rest copies that can defeat tree-shaking. The rule recognizes generated message imports, aliases and local scope, while allowing static message references and application-owned maps. Custom generated module paths can be added withmessageModules. No runtime, compiler output, or application behavior changes; the rule has no automatic fix because applications must choose their supported messages.Add optional lint setup to
paraglide-js initwith--lint eslint|oxlint|none, preserving existing lint configs via a dedicatedlint:i18nscript. Add--yes/--non-interactive, explicit project/output paths, and optional setup flags for unattended use. Closed input without an unattended flag fails before writes; headless mode skips optional editor/machine-translation prompts, protects dirty git trees unless explicitly allowed, reuses existing projects, preserves TypeScript config comments, and returns nonzero on setup/compile failures. No dependencies are installed automatically. -
32b54a8: Show compilation and config errors in Vite's development overlay, including in newly opened tabs. Once compilation and config loading recover, the plugin requests a page reload to clear the overlay. The dev server keeps serving the last compiled output, as before.
Patch Changes
-
08ef4de: Fix
extractLocaleFromHeaderpicking languages the client rejected withq=0and ranking ranges by malformed weights.fr; q=0.5andfr;Q=0.5were read as unknown tags, and weights likeq=abcorq=2were sorted asNaNor out-of-range numbers.Ranges with
q=0are now skipped, as RFC 9110 defines a weight of 0 as "not acceptable". Ranges whose weight is not a valid qvalue are skipped too. Theqparameter is matched case-insensitively, whitespace around;and=is tolerated, and other parameters are ignored, including quoted values that contain,or;.shouldRedirect()andparaglideMiddleware()reach this function through thepreferredLanguagestrategy, so their redirects follow the same rules. -
4889802: Bound filesystem concurrency for generated output across message modules, locale modules, declarations, and additional files. Propagate write, directory creation, and required deletion errors instead of silently reporting successful compilation with incomplete output. Drain active operations before rejecting, close the loaded project on failure, and preserve unchanged generated files when cleaning during a partial update.
-
bfdaecf: Cache Intl formatters used by compiled messages instead of constructing them on every call. Bound each formatter cache to 256 locale/options configurations, preserve direct-call option semantics, and include caching in middleware-injected messages.
Date/time formatters are cached only with an explicit time zone, so messages using the host default follow device or process time zone changes.
-
4dedc3f: Keep canonical callback responses unchanged in navigation redirect mode when built-in URL routing determines the locale. Canonicalization redirects only vary by
AcceptandSec-Fetch-Dest. -
bdb8f54: Reduce generated localization payloads by returning static text directly from locale dispatchers. Preserve locale switching, fallbacks, markup, middleware, and locale-specialized builds.
-
b43abc2: Skip locale splitting for callback values without response headers or a body reader, and for consumed or locked bodies. Keep HTML injection working when the global
Responseconstructor is replaced. -
ceaba90: Allow opt-in
outputStructure: "message-modules"with experimental per-locale Vite builds. Direct physical message imports let Vite retain page-specific messages in lazy chunks while specializing each graph to its selected locale. -
ae63a90: Keep protocol-relative hrefs in
localizeHref()anddeLocalizeHref()instead of dropping their host. For example, with localede,//cdn.example.com/docsnow becomes//cdn.example.com/de/docsinstead of/de/docs. This also handles/\and separators containing tabs or newlines. Explicit ports are preserved, including default ports such as:80. Links keep their implicit protocol on the server outside the middleware, wheregetUrlOrigin()uses a fallback origin. Configured protocol or port changes still produce absolute URLs. -
2ca1028: Cancel queued rebuilds when CLI watch mode shuts down, and ignore late watcher events or compile completions after shutdown. This prevents stopped watch sessions from recompiling or reopening file watchers.
-
2de79ed:
getLocale(),setLocale()andextractLocaleFromCookie()no longer throw whendocument.cookieorlocalStoragethrows, as both do with aSecurityErrorin sandboxed iframes withoutallow-same-originand other documents with an opaque origin. A failed read falls through to the next strategy. A failed write is skipped, sosetLocale()still navigates or reloads.The first
getLocale()call writes the cookie, so a page whose locale came from the URL used to throw on its first message. -
4c66c0d: Upgrade the minimum inlang SDK version to 4.0.4, bringing lower memory use and batched processing for large translation projects.
-
e14ee56: Include
Cookiein redirectVaryheaders when the route uses the cookie strategy. Responses fromresolvealso vary byCookieorAccept-Languagewhen the corresponding strategies come beforeurl, or when the URL does not supply a locale. Existing fields are kept without duplicates, andVary: *is unchanged.With the default strategy, HTTP responses now include
Vary: Cookie. Shared caches that honorVarydistinguish responses by the full Cookie header, which can reduce cache reuse. Mutable responses retain their identity; network error responses are passed through unchanged. Copied responses keep theirurl,redirectedandtype, including when cloned.
2.27.0
Minor Changes
-
45c276c: Upgrade note: compilation now fails with
… references the variable "count" in the local variable "countPlural", but "count" is not declaredwhen a local variable that the message uses reads a variable that has noinputdeclaration, such aslocal countPlural = count: pluralwithoutinput count. The inlang message format plugin before 4.4.1 imports such a local without adding theinput. These messages used to compile, and worked at runtime as long as the message had another input. Fix: add the missinginput countdeclaration, or update the inlang message format plugin to 4.4.1 or later, which adds it.Fix local variable compilation and support ICU plural offsets.
- A message function now declares only the local variables it reads, through match conditions, its patterns, or other locals it reads. Unread locals and an unread inputs parameter no longer fail TypeScript's
noUnusedLocalsandnoUnusedParametersin checked projects. - Local variables are emitted in dependency order, so a local that reads a local declared after it no longer throws a
ReferenceErrorat runtime. Locals that reference each other in a cycle now fail compilation with an error that names the message, the locale and the cycle. - A message that reads an undeclared variable, for example through
.local e = {$count}without.input {$count}, now fails compilation with an error that names the message, the locale and the variable. It used to compile to code that threwReferenceError: i is not definedor read an input missing from the message's type. Undeclared variables in patterns already failed compilation. pluralsupports theoffsetoption that ICU MessageFormat 1{count, plural, offset:1 …}imports as: the category is selected forcount - offset, while exact matches like=1comparecountitself.
- A message function now declares only the local variables it reads, through match conditions, its patterns, or other locals it reads. Unread locals and an unread inputs parameter no longer fail TypeScript's
-
6e5cfc5: Fix exact number matches on un-annotated local variables, and select variants in MessageFormat 2 preference order.
- A literal match on a local that aliases an input, such as
.local countPluralExact = {$count}from ICU{count, plural, =0 {…} one {…} other {…}}imports, now compares like a match on the input itself, so=0matches the number0(and the string"0"). Annotated locals (:plural,:number, …) still match their result as a string. - Variants are now tried in preference order: literal keys before catchalls, selector by selector, instead of in storage order. An exact
=0variant now wins over a plural category like Frenchone, and a catchall stored first no longer hides later variants. The=0variant wins only when its selector comes before the plural selector,countPluralExact, countPlural, as the ICU MessageFormat 1 plugin imports them. The inlang message format plugin up to 4.4.5 exports selectors alphabetically,countPlural, countPluralExact, so in files it wrote French0still selectsone: put the exact selector first inselectors.
Behavior change: a message whose variants relied on storage order may now select a different variant. The new choice is the one the MessageFormat 2 spec selects. For example, with selectors
platform, genderand the variants* male,android *,* *, the inputandroid+maleused to select* maleand now selectsandroid *. - A literal match on a local that aliases an input, such as
-
8921567:
paraglide-js initsets up translation checks.- New projects use
@inlang/plugin-message-format4.5.0 and@inlang/plugin-m-function-matcher2.3.0. initadds@inlang/cli^3.4.0 to the devDependencies (unless it's there) and acheck:i18nscript that runsinlang check --project ./project.inlang(unless a script of that name exists). It warns if an existing@inlang/cliis older than 3.4.0, which has noinlang check.- At the end,
initprints a localization section you can add to yourAGENTS.md, with your project path, message files and output directory. It doesn't writeAGENTS.md.
- New projects use
-
d58a9d6: Import the registry only where a message calls it, and format ICU
#.- A message file imported
registry.jswhenever its text containedregistry., including message text such as "Open the registry. Now.", which failed TypeScript'snoUnusedLocalsin checked projects. The compiler now records which registry functions each message calls and imports the registry only when one is called. - ICU MessageFormat 1
#(imported as{$count :icu:pound}) was an unknown formatter and printed the raw value. It now displays the number formatted for the locale like:number, minus the pluraloffsetwhen the import carries one ({$count :icu:pound offset=1}, see opral/inlang#4441).{count, plural, offset:1 … other {You and # others}}renders "You and 1,233 others" forcount1234 in English, instead of "You and 1234 others". Only numbers and numeric strings are formatted. Anything else is displayed as is, like{count}, without subtracting the offset:"abc","1,234"and""display unchanged,nullandundefineddisplay"null"and"undefined", and a bigint displays its digits unformatted, so it keeps its precision. The plural category is still selected onNumber(count)minus the offset, so without an offset""andnullselect the category of 0 (withoffset:1, the category of -1), and a bigint beyondNumber.MAX_SAFE_INTEGERloses precision there, as before. - With
experimentalMiddlewareLocaleSplitting, the messages the middleware injects into the page threwReferenceError: registry is not definedon the client when they called a registry function (:plural,:number,#, …). The injected script now declares the registry functions those messages call. - An
offsetfrom a variable (:plural offset=$offset,:icu:pound offset=$offset) no longer failscheckJs. Both functions type it asunknownand convert it withNumber(). - An unknown formatter on a local variable (
.local y = {$x :custom}) compiled toregistry.custom(...), which failedcheckJsand threw "registry.custom is not a function". It now interpolates the raw value with a warning, like an unknown formatter in a pattern. .parts()of a markup message failedcheckJs(Property 'parts' does not exist) when a locale's message had no markup of its own: a fallback to another locale, a message without markup, or the bundle id fallback. The bundle function now reads.partsthrough a type that declares it optional.
Behavior change:
#in messages imported with the ICU MessageFormat 1 plugin now renders locale-formatted numbers, as ICU does:1234renders as "1,234" in English and "1.234" in German, and fractions are rounded to at most three digits like:number. - A message file imported
-
8ee34b6: Requires
@inlang/sdk4.Paraglide now depends on
@inlang/sdk^4.0.0. Projects and plugins need no changes: plugins still exchange camelCasebundleIdandmessageId, and the compiled output is the same. If you callcompileProject()with anInlangProjectyou load yourself, load it with@inlang/sdk4. Code that writes toproject.dbdirectly uses the SDK 4 table and column names (inlang_bundle,bundle_id,message_id), see "Migrating to 4.0" in the SDK README.
Patch Changes
-
ffabe0a: The
README.mdin the compiled output is shorter and written for coding agents. It says to edit the translation files instead of the generated output, shows the compile command, explains what inlang owns versus Paraglide JS, and links to the inlang CLI (check,machine translate), Fink, Parrot and Sherlock. -
ba2ee63: Format
datetimewithout options in MessageFormat 2's default style,dateStyle=medium timeStyle=short.Without options that pick what to show (
dateStyle,timeStyle, or fields likeyear,month,hour),datetimeused the default ofIntl.DateTimeFormat, a numeric date like "10/9/2026". It now formats likedateStyle=medium timeStyle=short, the default of MessageFormat 2 (LDML 47), e.g. "Oct 9, 2026, 4:30 PM". Options that pick nothing, liketimeZoneandhour12, keep the default. For the defaults of ICU{d, date}and{d, time}, see "Format ICU MessageFormat 1 number, date and time styles".Behavior change:
datetimewithout options, such aslocal formattedDate = date: datetime, renders "Oct 9, 2026, 4:30 PM" instead of "10/9/2026". Passyear=numeric month=numeric day=numericfor the previous output. -
6a797cc: Format ICU MessageFormat 1 number, date and time styles.
The ICU MessageFormat 1 plugin imports
{n, number, integer}as{n: number style=integer},{d, date, short}as{d: date style=short}and{d, time, short}as{d: time style=short}.dateandtimewere unknown formatters and printed the raw value, e.g. "Fri Oct 09 2026 16:30:00 GMT+0200 (…)". They now format likedatetimewithdateStyleandtimeStyle(short,medium,long,full).{d, date}formats likedateStyle=mediumand{d, time}liketimeStyle=medium, ICU's defaults: "Oct 9, 2026" and "4:30:00 PM" in English.number style=integerpassedstyle: "integer"toIntl.NumberFormat, which threw aRangeErrorwhen the message was called. It now formats withmaximumFractionDigits: 0. Halves round away from zero likeIntl.NumberFormat(2.5renders "3"), while ICU rounds them to the nearest even integer (2.5renders "2").- A style without an
Intlequivalent, like an ICU skeleton ({n, number, ::currency/EUR},{d, date, ::yyyyMMdd}) orstyle=currencywithout acurrencyoption, threw when the message was called. It is now left out with a warning, and the value is formatted without it.
-
2b2ebf6: Prepare the compiler for
@inlang/sdk4. SDK 4 returns the bundle id of a message asbundle_idinstead ofbundleId. Given SDK 4 messages,compileMessage()andcompileBundle()read onlybundleId, so a message without a catch-all variant fell back to the string "undefined" instead of its bundle id, and errors namedmessage "undefined". They now read either name and throw if a message has no bundle id.compileMessage()accepts messages and variants in both shapes (CompilableMessage,CompilableVariant). The fallback also escapes bundle ids that contain"or\.
2.26.0
Minor Changes
- 58b570a: Speed up custom URL routing by skipping unrelated literal path prefixes and sharing a bounded compiled URLPattern cache across localization, locale extraction, route strategies, and static URL generation. Preserve pattern order and native matching, and refresh routing indexes and memoized results after configuration edits.
Patch Changes
- 0cb8daa: Fix the generated
runtime.jsandserver.jslosingimportlines from JSDoc@exampleblocks. The compiler strips each runtime module's own imports before inlining it, but the matcher was not anchored to the start of a line, so it also removedimport ... from '...'text inside doc comments together with the following newline, merging the remaining comment lines (for example* * m.hello(...)). The matcher is now anchored to the start of a line, so*-prefixed doc comment lines are kept while the modules' own imports are still stripped. - 9cc4ce1: Update the Inlang SDK dependency to 3.1.0.
2.25.4
Patch Changes
- afe6fdc: Fix default URL routing dropping trailing slashes when localizing or delocalizing paths. When
trailingSlashis omitted,/about/now becomes/en/about/and/en/about/delocalizes to/about/, matching equivalent explicit URL patterns. Paths without trailing slashes and localized root behavior remain unchanged. SettrailingSlash: "never"to explicitly generate slashless URLs;"always"continues to enforce trailing slashes.
2.25.3
Patch Changes
- e1e6e61: Upgrade the inlang SDK to 3.0.6 with Lix 0.17.0.
2.25.2
Patch Changes
- b26bada: Upgrade Inlang SDK to 3.0.5 with Lix 0.16.1 to fix compilation of sorted message files above 512 tracked-state rows. Includes transaction error handling and snapshot restoration fixes.
2.25.1
Patch Changes
- 845e819: Upgrade the Inlang SDK to 3.0.4, including Lix 0.15.1 fixes for transaction-local message and variant reads.
2.25.0
Minor Changes
-
f719e1f: Expose
cleanOutdir,experimentalStaticLocale, anddisableAsyncLocalStorageasparaglide-js compileCLI flags. -
5ed1745: Add support for a
paraglide.config.js(or.mjs,.ts,.cjs) configuration file inside the inlang project directory.The CLI and all bundler plugins now pick up compiler options from
<project>/paraglide.config.*. The project directory comes from--projector the plugin'sprojectoption and defaults to the conventional./project.inlang— which means every bundler plugin can now be instantiated without arguments. Since the config lives inside the project it configures, it cannot setprojectitself. Explicit flags and plugin options win over the config file, which wins over the built-in defaults. Existing setups keep working unchanged.Also included:
- A new
defineConfighelper exported from@inlang/paraglide-jsfor type inference and autocompletion in config files. - Watch modes reload when the active config file changes, including renames between the supported file names. Deleting all config files falls back to the built-in defaults; an invalid config skips the compilation with an error — watch modes keep serving the previous output, production builds fail loudly. (esbuild does not support config watching.)
cleanOutdiris accepted but ignored: watch integrations always preserve the output directory for incremental compilation.
- A new
Patch Changes
- aa4ffd3: Resolve references to earlier local variables correctly in message declarations and formatter options.
- 3634877: Fix
experimentalMiddlewareLocaleSplittingcorrupting the generated server file when a compiled message value contains a literal$(e.g. a price or currency symbol) that forms aString.replace()special replacement pattern such as$`. - 1bacc27: Fix
experimentalMiddlewareLocaleSplittingkeyingcompiledBundlesby the raw bundle id instead of the safe module id, so every SSR message lookup missed and threwglobalThis.__paraglide.ssr.<id> is not a functionon hydration.
2.24.1
Patch Changes
- d2aeb93: Update the inlang SDK dependency to 3.0.1, which includes the Lix WASM fallback for musl-based Node.js environments.
2.24.0
Minor Changes
- 7028c8a: Upgrade to
@inlang/sdkv3 and remove obsolete local account migration code.
Patch Changes
- 0ac907e: Cache compiled URL patterns to speed up repeated localized-link generation.
- fda90d2: Skip unchanged Vite compilations across dev-server restarts by persisting and validating the compiler input cache.
- 84e2766: Add a fast path for common locale-prefix and static-domain URL patterns while preserving the generic URLPattern fallback.
- 5de9441: Improve compiler output writes by using Node's synchronous SHA-256 implementation and only creating directories for generated files that changed.
- 5c17acf: Allow importing the programmatic compiler API without installing the optional Vite peer dependency.
- c52b523: Preserve request bodies in
paraglideMiddlewareby cloning body-bearing requests before rewrapping them, preventing "Body has already been read" errors on POST/PUT/PATCH/DELETE. - 32d285b: Avoid rewriting unchanged output files during one-shot CLI compilation.
- 9e1ee2e: Add an opt-in
trailingSlashcompiler option for canonicalizing localized URLs.
2.23.2
Patch Changes
- b8af4b1: Embed TypeScript sources in published JavaScript sourcemaps and stop emitting declaration sourcemaps that reference unpublished source files.
2.23.1
Patch Changes
- 6f9b062: Keep the server middleware's AsyncLocalStorage available when module instrumentation snapshots mutable exports.
2.23.0
Minor Changes
-
c2b9c17: Replace the experimental per-locale framework-output specialization with a Vite 8+ environment architecture.
experimentalPerLocaleBuild: truenow generates locale source modules before bundling, builds independent native Rolldown graphs, supports unminified builds and source maps, and emitsparaglide-vite-locales.jsonwithout rewriting completed chunks or framework output.Remove the private TanStack Start and SvelteKit renderer integrations. Those frameworks now require public client-variant build and render-selection APIs before they can compose with experimental per-locale builds.
Patch Changes
- 608385f: Use
baseLocaleas the exhaustive branch in generated message functions.
2.22.0
Minor Changes
- 2571af2: Add experimental Vite 8 per-locale client builds for TanStack Start and SvelteKit. Enable the same
experimentalPerLocaleBuild: trueflag in either framework; Paraglide detects the framework and serves compiler-specialized client assets for each locale.
2.21.0
Minor Changes
-
ab5bfc7: fix
emitTsDeclarationswith TypeScript 7 https://github.com/opral/paraglide-js/issues/711TypeScript 7 (the Go-based compiler) no longer ships the in-process compiler API that Paraglide used to generate
.d.tsfiles, which madeparaglide-js compile --emit-ts-declarationsfail withTypeError: Cannot read properties of undefined (reading 'ESNext'). Paraglide now detects this and invokes TypeScript'stscCLI instead. TypeScript 5 and 6 keep using the compiler API as before.Note that the declaration output of TypeScript 7 differs cosmetically from TypeScript 5/6 (quote style, declaration ordering,
export declare constvsexport const) but is semantically equivalent.
2.20.2
Patch Changes
- a48e767: Cache client cookie locale extraction for synchronous message bursts.
2.20.1
Patch Changes
- 8c3493d: Fix server cookie locale parsing when Cookie headers omit whitespace after semicolons.
2.20.0
Minor Changes
-
2c34351: Emit
messages/package.jsonwith{ "type": "module", "sideEffects": false }formessage-modulesoutput, declaring the generated message modules side-effect-free.This lets bundlers (notably Vite 8 / Rolldown) drop unused re-exports from the
mbarrel per entry, instead of bundling every message used anywhere in the app into one shared chunk that every entry downloads. Without it, per-page JS scales with the union of all messages used across the app rather than with the messages a given route actually uses.The declaration is scoped to
messages/, soruntime.js(which has real side effects) is unaffected.type: "module"is included because the package.json creates a new module scope formessages/; without it, the generated ESM files would default to CommonJS (a package.json withouttypeis CJS in Node, even when the consuming project istype: "module").
Patch Changes
- 921c3be:
experimentalMiddlewareLocaleSplitting: the injected inline script now reuses the nonce from the response'sContent-Security-Policyheader, so it is allowed under a strict CSP instead of being blocked and breaking hydration. Automatic - no configuration needed.
2.19.0
Minor Changes
-
67a8942: Compile pattern-level function-reference annotations to registry calls
Annotations attached directly to pattern expressions (e.g. i18next's
{{count, number}}imported via plugin-i18next) were silently dropped and compiled to plain interpolation. They now compile through the sameregistry.*path as local-variable annotations:// before const en_views = (i) => `${i?.count} views`; // after const en_views = (i) => `${registry.number("en", i?.count, {})} views`;Unknown formatter names fall back to plain interpolation with a compile-time warning instead of failing or staying silent.
compilePattern()gained an optionallocaleparameter, required to compile annotations. -
d57efa1: Skip recompilation when inputs are unchanged across bundler runs in the same process
vite buildfiresbuildStartonce per environment (client, ssr, ...) and each run did a fullcompile()— project loading and message compilation — even though the inputs hadn't changed. The plugin now hashes the tracked input files, their directory listings, and the output-affecting options after a successful compile, and skipscompile()entirely when the digest matches on the next run. The second and later environments become near-free:vite v6.4.1 building for production... ✔ [paraglide-js] Compilation complete (locale-modules) ✓ built in 634ms vite v6.4.1 building SSR bundle for production... ℹ [paraglide-js] Compilation skipped — inputs unchanged (locale-modules) ✓ built in 15msThe digest fails open: any state it can't certify (missing files, read errors, changed options, a failed compile) forces a recompile. Multi-compiler webpack setups (client + server) benefit the same way via
beforeRun.Also fixed along the way:
- A user-provided
fsoption silently bypassed the plugin's file-read tracking (the args spread overrode the tracked fs wrapper), which left file watching inert for custom-fs setups. - The watch-target filter ignored any path containing the substring "cache" — a project under e.g.
/cachet-app/had its inputs excluded from file watching. It now matches whole path segments only.
- A user-provided
Patch Changes
- 6010611: Update
@inlang/sdkto 2.10.0.
2.18.2
Patch Changes
-
4bea31a: Prevent
paraglide-js compile --watchfrom cleaning the output directory on the initial compile. -
4dfa099: Fix emitted TypeScript declarations for message keys that require quoted export aliases, such as dotted nested keys.
emitTsDeclarationsnow preserves quoted aliases from the generated JavaScript so.d.tsoutput remains valid for keys likegreeting.hello. The optional TypeScript peer dependency now requires TypeScript 5.6 or newer, which supports arbitrary quoted module export names.
2.18.1
Patch Changes
- 6eb7d02: Fix input match generation so
Infinityselectors match both numericInfinityvalues and string"Infinity"values. - c16730d: Pin default jsDelivr plugin URLs to exact versions in generated project settings.
2.18.0
Minor Changes
- 62d37f0: Add a
relativetimedeclaration formatter backed byIntl.RelativeTimeFormat.
Patch Changes
- a5f31bc: Update
@inlang/sdkto 2.9.3. - d2bf729: Mark
typescriptas an optional peer dependency and show a clear error whenemitTsDeclarationsis enabled without TypeScript installed. - ea8343f: Fix race condition where
paraglideVitePlugin(and the rollup/rolldown/rspack/esbuild plugins) wiped the output directory on every fresh process, racing concurrent reads from SSR/prerender modules and sibling Vite instances. The plugin now seedspreviousCompilationfrom existing on-disk hashes on the first compile, so warm restarts are a no-op (zero writes when inputs haven't changed) and the recursive wipe is gone. The webpack plugin's wipe behavior is unchanged but now also deletes orphaned files on its first compile. Closes #659.
2.17.0
Minor Changes
- 109e588: Add
--output-structureoption to the compile command.
2.16.1
Patch Changes
- 3bb446a: Update
@inlang/sdkto2.9.2.
2.16.0
Minor Changes
-
8401dae: Add new
paraglide-js compileCLI flags for compiler options that were previously only available through the programmatic API or bundler plugins.You can now:
- enable or disable emitted
.gitignore,.prettierignore, andREADME.md - explicitly enable or disable emitted
.d.tsfiles - pass a custom
isServerexpression for runtime tree-shaking
These options are forwarded through regular and
--watchcompiles so the CLI matches the existing compiler behavior more closely. - enable or disable emitted
2.15.3
Patch Changes
- b10186d: Fix numeric input match inference so generated message typings accept both numeric and string literal forms for values like
input=1, matching runtime behavior without relying on broad loose coercion.
2.15.2
Patch Changes
- c716c6d: Fix proxy-aware URL handling in
paraglideMiddleware(),shouldRedirect(), and locale extraction by adding aneffectiveRequestUrloverride for browser-facing URLs behind TLS-terminating proxies and load balancers. Addresses #652.
2.15.1
Patch Changes
- 2e8b5a1: Add markup documentation and message format plugin references to compiled README
- 8964e8b: Update
@inlang/sdkto2.9.1.
2.15.0
Minor Changes
-
862433c: Add
toLocale()for case-insensitive locale normalization, makeisLocale()strictly match canonical project locales, and return canonical locale values across runtime locale helpers.// configured locales: ["fr", "en-US"] isLocale("FR"); // false toLocale("FR"); // "fr" isLocale("en-us"); // false toLocale("en-us"); // "en-US"Runtime helpers that resolve locales from external input now return canonical project locale values as well.
2.14.1
Patch Changes
- 7d29058: Remove dead JSDoc
@importstripping from the runtime generator. - 46ac447: Upgrade
@inlang/sdkto v2.8.0.
2.14.0
Minor Changes
- 067509d: Improve generated runtime typing by centralizing shared type definitions, avoiding strict
checkJslocale type errors, and moving middleware locale-splitting state underglobalThis.__paraglide.ssr.
Patch Changes
- a17af28: Remove stale telemetry internals that were no longer used by the CLI or compiler.
2.13.2
Patch Changes
-
2e18cc0: Fix compiler code generation for formatter option literals so Intl numeric and boolean options are emitted with the correct literal types.
This resolves strict
checkJs/svelte-checkerrors where generatednumber()options likeminimumFractionDigitswere emitted as strings and causedType 'string' is not assignable to type 'number'.
2.13.1
Patch Changes
-
9d79aff: Fix single-locale message generation to avoid emitting an unused
localevariable in strict TypeScriptcheckJssetups. This removesTS6133('locale' is declared but its value is never read) warnings for generated message files when only one locale is configured.Add a regression type test that asserts single-locale generated messages do not produce this warning.
2.13.0
Minor Changes
-
7185902: Add a new runtime utility:
getTextDirection(locale?).- Returns
"ltr"or"rtl"for a given locale. - Defaults to the current locale from
getLocale()when no locale is provided. - Uses
Intl.Localetext info when available, with a safe RTL fallback for runtimes without that API.
Also updates SvelteKit example/docs to show setting both
%lang%and%dir%inapp.htmlusing runtime APIs. - Returns
2.12.0
Minor Changes
-
af0084e: Add route-level locale strategy overrides via
routeStrategies.You can now define per-route strategy behavior (first match wins), including:
strategyoverrides for paths like/dashboard/*and/rpc/*exclude: trueto skip i18n middleware behavior for paths like/api/*
2.11.0
Minor Changes
-
d1c86fb: Improve emitted message-module output by gating middleware locale-splitting hooks behind
experimentalMiddlewareLocaleSplitting.When the option is disabled (default), generated message functions no longer emit:
if (experimentalMiddlewareLocaleSplitting && isServer === false) { ...__paraglide.ssr... }trackMessageCall(...)- related runtime imports (
experimentalMiddlewareLocaleSplitting,isServer,trackMessageCall)
When
experimentalMiddlewareLocaleSplittingis enabled, the existing SSR/middleware injection flow is preserved. -
90a1580: Add compiler support for markup messages with a new
message.parts()API.Messages that contain markup now compile to framework-neutral parts (
text,markup-start,markup-end, andmarkup-standalone) whilemessage()continues to return plain strings.
2.10.0
Minor Changes
-
fc66ee1: Add type-safe literal unions for match variants in generated message typings https://github.com/opral/paraglide-js/issues/538.
For example, the following minimal message definition:
{ "auth_password_error": [ { "match": { "type=empty": "You must provide a password" } } ] }Before:
m.auth_password_error({ type: "typo" }); // ✅ OK (typed as NonNullable<unknown>)After:
m.auth_password_error({ type: "typo" }); // 💥 Type error
2.9.1
Patch Changes
- c43effb: Update
@inlang/sdkto v2.6.2, which removes a file queue settlement that could prevent the compiler from exiting in some environments. See https://github.com/opral/paraglide-js/issues/598.
2.9.0
Minor Changes
- badca6a: Add the experimental
experimentalStaticLocalecompiler option for per-locale tree-shaking (see https://github.com/opral/paraglide-js/issues/88#issuecomment-3634754638). - a0c5665: Prune async_hooks import from generated server output when async local storage is disabled (fixes https://github.com/opral/paraglide-js/issues/539).
Patch Changes
-
9ae2381: Add
@seedocumentation links to runtime and server APIs, making it easier for developers to find relevant documentation directly from their IDE. -
867ea44: Avoid cyclic fallback maps when a language-only locale exists alongside a regional base locale.
Previously, a setup like
locales: ["it", "it-IT"]withbaseLocale: "it-IT"could create a fallback cycle (it → it-IT → it) and throw a runtime error. The compiler now breaks that cycle by making thebaseLocaleterminal, soit-ITno longer falls back toitwhileitstill falls back toit-IT. -
3cbdd75: Fix message compilation for input names with non-identifier characters (like
half!).Before: i18next-style placeholders with symbols produced invalid JS because we emitted
i.half!in patterns, local variables, and match conditions (syntax error). Now: Paraglide quotes the key in JSDoc and uses bracket access in generated code (e.g.i["half!"]), so the same message compiles and runs correctly.-// before (invalid JS) -// input: { "half!": "1st" } -return `${i.half!} Half - Corner Handicap` +// after (valid JS) +// input: { "half!": "1st" } +return `${i["half!"]} Half - Corner Handicap` -
deb9877: Avoid locale/message name collisions in the locale-modules output structure by prefixing locale imports.
Previously, a locale like
nocould collide with a message keyno, causing duplicate symbol errors in the generatedmessages/_index.js. Now, locale imports are prefixed (e.g.__no), keeping message exports intact and avoiding the conflict.
2.8.0
Minor Changes
-
07e17c0: Emit a
README.mdin the compiled output to help LLMs understand the generated code. The README includes usage examples, runtime API documentation, and links to further resources. Can be disabled withemitReadme: false. -
991c314: Improve watch mode to monitor directories so newly added translation files trigger recompiles in the CLI and bundler plugin.
-
4a75259: Update inlang SDK to v2.6.0 with improved project structure and forward-compatibility.
New
.meta.jsonfile in inlang projects:The SDK now writes a
.meta.jsonfile to track which SDK version last modified the project. This enables safe forward migrations and prevents accidental downgrades when switching between SDK versions.project.inlang/ settings.json README.md .gitignore .meta.json <-- newUpdated
.gitignorehandling:Inlang projects now manage their own
.gitignorethat ignores everything exceptsettings.json. If you see the.gitignorefile inside your.inlangproject folder showing up as changed in git, run these commands to fix it:# Remove the tracked .gitignore from git's index git rm --cached '**/*.inlang/.gitignore' # Commit the change git commit -m "fix: remove tracked .gitignore from inlang project"This is a one-time fix. The inlang SDK handles the
.gitignoreautomatically starting with v2.5.
Patch Changes
- ec7f3e3: Add a
--watchflag to the CLIcompilecommand to recompile on changes. - be10228: Strip sourcemap references from generated runtime and server outputs to avoid missing map warnings. (https://github.com/opral/paraglide-js/issues/581)
- e75e2a3: Add documentation for avoiding redirect loops with frameworks that handle URL localization themselves (e.g., TanStack Router).
- Added JSDoc example in
paraglideMiddleware()explaining when to use the original request vs the modified request - Added troubleshooting section in SSR docs explaining the redirect loop issue and solution
- Updated TanStack Start example README with an important callout about using the original request
- Added JSDoc example in
2.7.2
Patch Changes
- 983d893: Added a defensive try catch request cloning in
paraglideMiddlewarefor runtimes with customRequestwrappers (TanStack Start 1.143+: https://github.com/TanStack/router/issues/6089, https://github.com/opral/paraglide-js/issues/573).
2.7.1
Patch Changes
- update
@inlang/sdkto2.4.10which contains a fix for dynamically loading plugins in bun https://github.com/opral/monorepo/pull/3787.
2.7.0
Minor Changes
-
Add an opt-in
emitTsDeclarationscompiler flag to generate.d.tsfiles for the compiled output.This is useful when
allowJs: truecannot be set in yourtsconfig.json(e.g., due to project constraints or conflicting compiler options).Usage:
// vite.config.ts import { defineConfig } from "vite"; import { paraglideVitePlugin } from "@inlang/paraglide-js"; export default defineConfig({ plugins: [ paraglideVitePlugin({ project: "./project.inlang", outdir: "./src/paraglide", emitTsDeclarations: true, }), ], });Or via CLI:
paraglide compile --project ./project.inlang --outdir ./src/paraglide --emitTsDeclarationsNote: Enabling this option reduces compiler speed because TypeScript needs to generate declaration files for all output modules.
Closes https://github.com/opral/inlang-paraglide-js/issues/566 Closes https://github.com/opral/inlang-paraglide-js/issues/238 Closes https://github.com/opral/inlang-paraglide-js/issues/160
Example output (locale-modules):
src/paraglide/ messages/ _index.js + _index.d.ts de.js + de.d.ts en.js + en.d.ts messages.js + messages.d.ts
2.6.0
Minor Changes
-
3d6259c: Add
LocalizedStringbranded type for compile-time i18n safety.Message functions now return
LocalizedStringinstead ofstring, enabling TypeScript users to distinguish between translated and untranslated strings at compile time. This is fully backward compatible since branded types are assignable to their base type.import { m } from "./paraglide/messages.js"; import type { LocalizedString } from "@inlang/paraglide-js"; const greeting: LocalizedString = m.hello(); // ✓ Type-safe const raw: LocalizedString = "Hello"; // ✗ Type error -
4bde3eb: Add optional chaining to compiled message inputs so missing inputs no longer throw at runtime; include tests covering single- and multi-variant messages.
Closes https://github.com/opral/inlang-paraglide-js/issues/568
Example:
// compiled translation export const greeting = (i) => `Hello ${i?.name}`; // TypeScript still enforces the input shape; this is purely runtime safety (handy in dev). greeting(); // no throw, returns "Hello undefined" greeting({ name: "Ada" }); // "Hello Ada" // previously (boom 💥) export const greetingOld = (i) => `Hello ${i.name}`; greetingOld(); // TypeError: Cannot read properties of undefined (reading 'name')
2.5.0
-
72d1c53: Ensure the CLI honours allowJs flags defined in extended or referenced tsconfig files instead of prompting unnecessarily.
Refs https://github.com/opral/inlang-paraglide-js/issues/560.
-
c59da26: fix: make locale matching case-insensitive
Closes https://github.com/opral/inlang-paraglide-js/issues/549
This fixes an issue that locales containing uppercase characters like
pt-BRfailed to load when usingextractLocaleFromNavigatororextractLocaleFromHeader.The issue occurred because these functions converted locales to lowercase, while the comparison logic inside
assertIsLocaleandisLocalewasn't case-sensitive.List of changes:
- Ensured locale comparisons in
assertIsLocale()andisLocale()are fully case-insensitive. - Made
assertIsLocale()return the canonical-cased locale fromlocalesinstead of the raw input. - Added new test coverage for case-insensitive behavior in
assertIsLocale()andisLocale().
- Ensured locale comparisons in
-
9735b82: Fix fallback assignment generation so locale chains emit dependencies first and avoid "Block-scoped variable used before its declaration" errors. See https://github.com/opral/inlang-paraglide-js/issues/507 for details.
2.4.0
Minor Changes
- 4111ee6: Add an isomorphic
shouldRedirect()helper shared by the middleware and client routers, improve redirect typing, and document the new API in the URL strategy guide.
Patch Changes
-
4a48c07: fix: fix eslint incorrectly linting generated files
closes https://github.com/opral/inlang-paraglide-js/issues/558
eslint ignores single-line 'eslint-disable' comments at the start of a file. Using a block comment without a closing one instead will prompt eslint to ignore it.
- output[filename] = `// eslint-disable\n${content}`; + output[filename] = `/* eslint-disable */\n${content}`; -
4c8921f: Fixes
overwriteSetLocaleto keep the full(locale, options?)signature when overridingsetLocale, preventing TypeScript from rejecting calls that pass{ reload: false }. Adds a regression test ensuring custom handlers receive the options object. -
Updated dependencies [7791be7]
- @inlang/sdk@3.0.0
2.3.2
Patch Changes
- 4ea9e7a: fix: ensure that async custom setLocale funcs resolve with reload: false
2.3.1
Patch Changes
- 090964b: fix(runtime/set-locale.js): ensure reload waits for async custom setLocale funcs https://github.com/opral/monorepo/pull/3692
2.3.0
Minor Changes
- bfe8518: Crash the build process (for example during
vite build) if paraglide can't compile the project. - Removed local account loading which suddenly led to crashes for some users.
2.2.0
Minor Changes
-
69ac911: Add support for async custom server strategies with
extractLocaleFromRequestAsyncThis change introduces a new
extractLocaleFromRequestAsyncfunction that supports asynchronous custom server strategies, enabling use cases like fetching user locale preferences from databases.What's Changed
- New Function: Added
extractLocaleFromRequestAsyncthat supports async custom server strategies - Middleware Update: Server middleware now uses the async version to support async custom strategies
- Breaking Change: The synchronous
extractLocaleFromRequestno longer supports custom server strategies - Improved Documentation: Added comprehensive examples and usage guidance
Migration Guide
For users with custom server strategies:
Before:
// This no longer works in sync version defineCustomServerStrategy("custom-database", { getLocale: async (request) => { return await getUserLocaleFromDatabase(request); }, }); const locale = extractLocaleFromRequest(request); // Won't call async custom strategiesAfter:
// Use the async version for custom strategies defineCustomServerStrategy("custom-database", { getLocale: async (request) => { return await getUserLocaleFromDatabase(request); }, }); const locale = await extractLocaleFromRequestAsync(request); // Supports async custom strategiesFor users calling
extractLocaleFromRequestdirectly:If you're using
extractLocaleFromRequestdirectly in your code without custom strategies, no changes are needed. For custom server strategies, switch toextractLocaleFromRequestAsync.The server middleware automatically uses the async version, so no changes are needed for standard middleware usage.
Closes https://github.com/opral/inlang-paraglide-js/issues/527
- New Function: Added
Patch Changes
-
5589e30: (likely) fix: handler is of type
unknownts error https://github.com/opral/inlang-paraglide-js/issues/529 -
3712f09: Fix cookieDomain default behavior for better server/client cookie compatibility.
When
cookieDomainis undefined or empty, cookies are now set without a domain attribute, scoping them to the exact current domain only (no subdomains). This fixes compatibility issues with server-side cookies that don't include a domain attribute.Before:
// When cookieDomain was undefined, cookies were set as: document.cookie = "PARAGLIDE_LOCALE=en; path=/; max-age=34560000; domain=example.com"; // This made cookies available to subdomainsAfter:
// When cookieDomain is undefined, cookies are now set as: document.cookie = "PARAGLIDE_LOCALE=en; path=/; max-age=34560000"; // This scopes cookies to the exact current domain onlyMigration:
- If you want the previous behavior (subdomain sharing), explicitly set
cookieDomainin your configuration:
paraglideWebpackPlugin({ project: './project.inlang', outdir: "./src/paraglide", + cookieDomain: 'example.com' }) - If you want the previous behavior (subdomain sharing), explicitly set
2.1.0
Minor Changes
-
4255bd5: Provide functions for getting the preferred language on server and client.
This defines two new functions for getting the preferred language:
extractLocaleFromHeader: Extracts the locale from the accept-language header on the server.extractLocaleFromNavigator: Extracts the locale from the navigator.languages array on the client.
The code was already present in the
@inlang/paraglide-jspackage, but it was not exported. Now it is exported so that it can be used in custom strategies. -
dc287f1: Implement custom strategy concept for locale resolution.
This introduces a new way to define custom locale resolution strategies alongside built-in strategies. Custom strategies provide a cleaner, more composable approach compared to overwriting
getLocale()andsetLocale()functions directly.New APIs:
defineCustomClientStrategy(): Define custom strategies for client-side locale resolutiondefineCustomServerStrategy(): Define custom strategies for server-side locale resolution
Key features:
- Custom strategies must follow the pattern
custom-<name>where<name>contains only alphanumeric characters - Can be combined with built-in strategies in the strategy array
- Respect strategy order for fallback handling
- Support both client and server environments
- Provide better error isolation and type safety
Usage example:
import { defineCustomClientStrategy } from "./paraglide/runtime.js"; defineCustomClientStrategy("custom-sessionStorage", { getLocale: () => sessionStorage.getItem("user-locale") ?? undefined, setLocale: (locale) => sessionStorage.setItem("user-locale", locale), });Then include in your strategy configuration:
compile({ strategy: ["custom-sessionStorage", "cookie", "baseLocale"], });
Patch Changes
-
4c0b997: perf(paraglide): improve bundle size by removing message id fallback for fully translated messages
-
9621803: Add Vary: Accept-Language header when preferredLanguage strategy is used
Paraglide middleware now automatically sets the
Vary: Accept-Languageheader when performing redirects based on thepreferredLanguagestrategy. This indicates to clients (CDN cache, crawlers, etc.) that the response will be different depending on theAccept-Languageheader, ensuring proper caching behavior and SEO compliance.Closes https://github.com/opral/inlang-paraglide-js/issues/522
-
Updated dependencies [22089a2]
- @inlang/sdk@2.4.9
2.0.13
Patch Changes
-
688c7c8: Add support for callbacks in server middleware
-
635861b:
extractLocaleFromUrl()now uses a cache for the last value.Useful on the client-side where the same URL is being extracted many times for each message on a given page.
2.0.12
Patch Changes
- 31337ba: expose
createParaglide() - Updated dependencies [56acb22]
- @inlang/sdk@2.4.8
2.0.11
Patch Changes
-
de0439f: Add domain property to cookie options.
paraglideVitePlugin({ project: './project.inlang', outdir: "./src/paraglide", + cookieDomain: 'example.com' }),
2.0.10
Patch Changes
- d16e853: fix: [2.0.8] Adds extra */ in generated .js files https://github.com/opral/inlang-paraglide-js/issues/493
2.0.9
Patch Changes
- Updated dependencies [bd2c366]
- @inlang/sdk@2.4.7
2.0.8
Patch Changes
-
5258af0: fix: compiling message bundles with case sensitive ids for the locale module output https://github.com/opral/inlang-paraglide-js/issues/490
Case sensitive ids led to duplicate exports in the locale module output. This has been fixed by adjusting the
toSafeModuleId()used by the compiler internally to append a number of uppercase characters to de-duplicate the ids.toSafeModuleId("helloworld") "helloworld" toSafeModuleId("helloWorld") - "helloworld" + "helloworld1"
2.0.7
Patch Changes
- 48931f5: make
output-structure: locale-modulesthe default for dev builds https://github.com/opral/inlang-paraglide-js/issues/486 - Updated dependencies [49a7880]
- @inlang/sdk@2.4.6
2.0.6
Patch Changes
- 3fa27c0: fix: duplicate (case sensitive) message keys leading to compile error when using
output-structure: locale-modules. closes https://github.com/opral/inlang-paraglide-js/issues/487 - 02c2d34: improve: compiler should log warnings when plugins can not be imported
- Updated dependencies [083ff1f]
- @inlang/sdk@2.4.5
2.0.5
Patch Changes
-
698b9a9: add
cookieMaxAgeoption to compiler and runtimeCloses https://github.com/opral/inlang-paraglide-js/issues/483
- Introduced
cookieMaxAgeoption toCompilerOptions, allowing configuration of cookie expiration time. - Adjusted tests to verify
max-agein cookies.
- Introduced
2.0.4
Patch Changes
- @inlang/sdk@2.4.4
2.0.3
Patch Changes
- cf404e0: improve: handle duplicate inputs https://github.com/opral/inlang-paraglide-js/issues/479
2.0.2
Patch Changes
- a6c43ea: fix: error handling in paraglideMiddleware breaks SvelteKit features that rely on errors being thrown
2.0.1
Patch Changes
- b906c0c: fix: window undefined bug in webpack
- @inlang/sdk@2.4.3
Paraglide JS 2.0 🚀
Paraglide JS 2.0 had three main goals which have all been achieved:
- Use the new inlang SDK v2 which supports variants #201.
- Unify the API across any framework #217.
- Support any i18n strategy (cookie, url, domain, session, etc).
- 🌐 Variants (pluralization) are now supported docs
- 😍 No more adapters or providers are needed (!)
- 🛣️ Any strategy (url, cookie, local storage) is now supported docs
In addition, Paraglide JS 2.0 comes with:
- 🌟 Nested message keys are now supported (most requested feature!)
- ✨ Auto-imports when writing
m.(no more manualimport * as m) - 🍌 Arbitrary key names including emojis via
m["🍌"]() - 🔄 Incremental migration to Paraglide JS is now possible
- 🏘️ Multi-tenancy support for domain-based routing
- 🔧 Exposing the compiler API for advanced workflows
- 🛣️ Configurable routing strategies (URL, cookie, domain, etc)
- 🧪 Experimental per-locale splitting for decreasing bundle sizes
- 🌐 Framework-agnostic server middleware for SSR (SvelteKit, Next.js, etc)
Highlights
Interactive benchmark
Check out the benchmark to see how Paraglide JS compares to other libraries like i18next.
No more adapters are needed
- @inlang/paraglide-sveltekit
- @inlang/paraglide-next
+ // No more adapters are needed
🚀 Framework-Agnostic Server Middleware
Docs are here
- New: Universal
paraglideMiddleware()works in any SSR framework - Built-in: Automatic locale redirects when user preference detected
// SvelteKit example - same pattern works for Next.js, Astro, etc.
import { paraglideMiddleware } from "./paraglide/server.js";
export const handle = ({ event, resolve }) => {
return paraglideMiddleware(event.request, () => resolve(event));
};
🛣️ Configurable Routing Strategies
Read more about strategies on the docs.
Literally anything is now possible. URL-based, domain-based, path-based, cookie-based, etc.
paraglide({
strategy: [
"url",
"cookie",
"preferredLanguage",
"..."
],
}),
🔧 Exposing the compiler API
- New: Direct compiler access for advanced workflows
- Why: Enable CI/CD pipelines and custom tooling
- Benefit: Full control over compilation timing/caching
// New programmatic API
import { compile } from "@inlang/paraglide-js";
await compile({
project: "./project.inlang",
outdir: "./src/paraglide",
});
🍌 Arbitrary key names
- New: Arbitrary key names including emojis via `m"🍌"
- Why: Enable nesting of messages
- Benefit: More expressive and fun translations
// Paraglide 1.0
m.some_message(); // ✅ Works
m.nested.message(); // 💥 Error
// Paraglide 2.0
m.some_message(); // ✅ Works
m["nested.message"](); // ✅ Works
// Even emojis are supported
m["🍌"]();
🔄 Incrementally migrating to Paraglide JS
Paraglide JS 2.0 can load multiple translation file formats. As such, you can incrementally migrate to Paraglide JS with existing translation file formats.
// In this example, Paraglide JS compiles i18next translation files
// which enables using both i18next and Paraglide JS.
import i18next from "i18next";
import { m } from "./paraglide/messages.js";
console.log(i18next.t("greeting", { name: "World" }));
console.log(m.greeting({ name: "World" }));
🏘️ Multi-tenancy support
Paraglide JS 2.0 supports multi-tenant applications. Read more about it here.
# Domain-based with sub-locale
customer1.fr/about → French (default)
customer1.fr/en/about → English version
# Domain-based with root locale
customer2.com/about → English (default)
customer2.com/fr/about → French version
# Path-based for any domain
example.com/en/about → English
example.com/fr/about → French
app.example.com/en/about → English
app.example.com/fr/about → French
Migrating breaking changes
If problems arise, please refer to the framework-specific getting started guide:
LanguageTag got renamed to locale
To align with industry standards, we renamed LanguageTag to locale.
-languageTag()
+getLocale()
-setLanguageTag()
+setLocale()
-availableLanguageTags
+locales
Remove adapters @inlang/paraglide-* from your dependencies
// package.json
{
"dependencies": {
- "@inlang/paraglide-sveltekit": "^1.0.0",
- "@inlang/paraglide-next": "^1.0.0",
- "@inlang/paraglide-astro": "^1.0.0",
- "@inlang/paraglide-vite": "^1.0.0",
+ "@inlang/paraglide-js": "^2.0.0",
}
}
```
### Replace adapter bundler plugins
```diff
// vite.config.js
-import { paraglide } from "@inlang/paraglide-vite";
+import { paraglideVitePlugin } from "@inlang/paraglide-js";
export default defineConfig({
plugins: [
- paraglide({
+ paraglideVitePlugin({
project: "./project.inlang",
outdir: "./src/paraglide",
}),
],
});
Remove Paraglide Providers
Paraglide JS 2.0 no longer requires providers.
// app.tsx, layout.svelte, etc.
-import { ParaglideProvider } from "@inlang/paraglide-{framework}";
function App() {
return (
- <ParaglideProvider>
<YourApp />
- </ParaglideProvider>
)
}
Shorten key names longer than 255 characters
Paraglide JS 2.0 build output now defaults to message-modules to improve tree-shaking. Some filesystem's limitations require key names to be shorter than 255 characters.
Upvote #423 to remove this limitation.
- m.this_is_a_very_long_key_name_that_should_be_shortened()
+ m.shortened_key_name()
Changing the locale requires a reload
Changing the locale works via setLocale() in any framework now.
If you used an adapter in v1 like the SvelteKit one, this behavior is new. The new behaviour leads to a page reload. The reload is a deliberate design decision. Reloading the site eliminates the need for providers, adapters, and API differences between frameworks. Furthermore, optimizations like per-locale splitting is expected to be easier to implement.
Read https://github.com/opral/inlang-paraglide-js/issues/438#issuecomment-2703733096 for more information.
-<a href="/de">Deutsch</a>
+<button onclick="setLocale('de')">Deutsch</button>
Lint rules were deprecated
Remove lint rules from your project modules.
We want to re-introduce lint rules in a better form in the future. Please upvote the #239 lix validation rules proposal.
modules: [
- "https://cdn.jsdelivr.net/npm/@inlang/message-lint-rule-missing-translation@latest/dist/index.js",
- "https://cdn.jsdelivr.net/npm/@inlang/message-lint-rule-empty-pattern@latest/dist/index.js"
...
]
localizeHref() is now required
Some Paraglide adapters used AST transforms to automatically transform <a> into localized links. That led to many bugs and edge cases. The AST transforms were removed for v2.
-<a href="/page"></a>
+<a href={localizeHref("/page")}
2.0.0-beta.31 (released as 2.0.0)
-
feat: New API:
createParaglide()The function allows a no build step or before build step access to Paraglide's compiled APIs.
const project = await fs.readFile("./project.inlang"); const paraglide = await createParaglideModule({ project, compilerOptions: { strategy: ["url"], }, }); // Use runtime functions paraglide.localizeUrl("https://example.com", { locale: "de" }); // Use server middleware app.use(paraglide.paraglideMiddleware()); -
fix:
getLocalereturns correct value on SvelteKit server #461 -
fix: Prevent redirect loops by normalizing URLs with trailing slashes #408
-
fix: Support for explicit port numbers in URL patterns
-
improve: Better error handling in server middleware
2.0.0-beta.30
-
improve: if no url pattern matches,
localizeUrl()anddeLocalizeUrl()will return the input url unchanged instead of throwing an error #452 -
improve: make AsyncLocalStorage tree-shakable by moving
disableAsyncLocalStorageinto the compiler options #424
- serverMiddleware(req, resolve, { disableAsyncLocalStorage: true })
+ serverMiddleware(req, resolve)
paraglideVitePlugin({
// ...
+ disableAsyncLocalStorage: true
})
- improve: allow fall through. enables partially localized patterns and thereby eases adoption.
2.0.0-beta.29
2.0.0-beta.28
BREAKING update to the URLPattern API
https://github.com/opral/monorepo/pull/3485
The localizedNamedGroups and deLocalizedNamedGroups API has been replaced with a tuple-based localized array to:
- enable translated pathnames in any combination
- make the API more intuitive
Migration Guide:
Refer to the updated documentation here.
Before
{
"pattern": "https://:domain(.*)/:locale(de|fr)?/:path*",
"deLocalizedNamedGroups": { "locale": null },
"localizedNamedGroups": {
"en": { "locale": null },
"fr": { "locale": "fr" },
"de": { "locale": "de" }
}
}
After
{
"pattern": "https://:domain(.*)/:path*",
"localized": [
["fr", "https://:domain(.*)/fr/:path*"],
["de", "https://:domain(.*)/de/:path*"]
["en", "https://:domain(.*)/:path*"],
]
}
other changes
-
improve: fallback to
typeof windowin vite #445 -
make
setLocale()set all strategies. Setting all strategies aligns with user expectations and ensures that server APIs can receive the cookie of the client, for example. #439 -
new
generateStaticLocalizedUrls()API #443
const localizedUrls = generateStaticLocalizedUrls([
"/example",
"/page/blog",
"/123/hello"
])
console.log(localizedUrls.map(url => url.pathnames))
>> /de/example
>> /fr/example
>> ...
2.0.0-beta.27
- fix wrong matching in API requests #427
Paraglide JS is no longer extracting the locale from API requests for the url strategy because that can lead to unwanted re-directs. To get the right locale in API requests, at least add the baseLocale strategy to your options.
-strategy: ["url"]
+strategy: ["url", "cookie", "baseLocale"]
-
consolidated
message-modulesoutput into a single file #434 to severaly improve scalability -
experimentalMiddlewareLocaleSplittingoption https://github.com/opral/inlang-paraglide-js/issues/425#issuecomment-2692351073 -
fix serverMiddleware() throws when cookie contains invalid locale
-
add
localStoragestrategy #431 -
fix url strategy with optional locale always resoles base locale #436
2.0.0-beta.26
- replace
node:cryptowith the Web Crypto API https://github.com/opral/inlang-paraglide-js/issues/424
2.0.0-beta.25
- added optional localized groups
- keeps hashes, etc. in the URL when localizing https://github.com/opral/monorepo/pull/3452
- fixes the multi-variant return
2.0.0-beta.24
- changes the redirect status from
302to307https://github.com/opral/inlang-paraglide-js/issues/416 - adds a
cleanOutdiroption which defaults to true https://github.com/opral/inlang-paraglide-js/issues/420 - adds a
machine-translatecommand if desired on init
2.0.0-beta.23
Renames and splits the serverMiddleware() into a dedicated server.js file to avoid bundler issues.
- import { serverMiddleware } from "./paraglide/runtime.js";
+ import { paraglideMiddleware } from "./paraglide/server.js";
2.0.0-beta.22
- fix
serverMiddleware()only imports async_hooks on the server - add
serverMiddleware(req, resolve, { disableAsyncLocalStorage: true })to disable async local storage - fix
serverMiddleware()throws in next js whenurlstrategy is not used https://github.com/opral/inlang-paraglide-js/issues/411#issuecomment-2683530533
2.0.0-beta.21
- compile arbitrary message keys https://github.com/opral/inlang-paraglide-js/issues/201#issuecomment-2680006131
- only polyfills
URLPatternif needed https://github.com/opral/inlang-paraglide-js/issues/381 - don't include
urlstrategy by default https://github.com/opral/inlang-paraglide-js/issues/405 - fixes webpack watch mode https://github.com/opral/inlang-paraglide-js/issues/406
2.0.0-beta.20
- automatic re-directs in
serverMiddleware()https://github.com/opral/inlang-paraglide-js/issues/201#issuecomment-2675823651 - various bug fixes and improvements
2.0.0-beta.19
NO MORE ADAPTERS NEEDED.
If you have code from an adapter, remove it and follow the examples in the documentation. https://paraglidejs.com/sveltekit
-@inlang/paraglide-sveltekit
-@inlang/paraglide-next
-@inlang/paraglide-astro
-
introduced
serverMiddleware()https://github.com/opral/inlang-paraglide-js/issues/201#issuecomment-2673375348 -
rename
defineGetLocale()anddefineSetLocale()tooverwriteGetLocale()andoverwriteSetLocale()https://github.com/opral/inlang-paraglide-js/issues/382 -
enables
import { m } from "./paraglide/messages.js"for auto imports https://github.com/opral/inlang-paraglide-js/issues/345 -
adds the
strategycompiler option to the cli https://github.com/opral/inlang-paraglide-js/issues/316
2.0.0-beta.18
Added URLPatterns as a replacement for the beta 17 pathnames API.
The URLPattern API is extremly powerful. You can express base paths, translated pathnames, domain based localization, and even multi-tenancy.
Read the docs here and make PRs to improve the documentation.
await compile({
- strategy: ["pathname"],
+ strategy: ["url"],
})
The localizePath() API had to be replaced by a new localizeHref() API. Please give feedback on the new API in #380
- <a href={localizePath("/about")}>About</a>
+ <a href={localizeHref("/about")}>About</a>
2.0.0-beta.17
Add support for pathnames API https://github.com/opral/inlang-paraglide-js/issues/359
You can now create whatever pathname pattern you want. The syntax is provided by https://github.com/pillarjs/path-to-regexp.
await compile({
strategy: ["pathname", "cookie", "baseLocale"],
+ pathnames: {
+ "{*path}": {
+ "de": "/de{/*path}",
+ "en": "/en{/*path}",
}
}
})
Add support for pathnameBase https://github.com/opral/inlang-paraglide-js/issues/362
await compile({
strategy: ["pathname", "cookie", "baseLocale"],
+ pathnameBase: "/base"
})
2.0.0-beta.16
New strategy API. See https://github.com/opral/inlang-paraglide-js/issues/346.
You can now define your own stragegy for getting and setting a locale.
await compile({
+ strategy: ["pathname", "cookie", "baseLocale"]
})
2.0.0-beta.14
Fixes windows path normalization https://github.com/opral/monorepo/pull/3374
2.0.0-beta.13
- flat compiler options
await compile({
- compilerOptions: {
- emitPrettierIgnore: false,
- },
+ emitPrettierIgnore: false,
})
- removed
experimentalEmitTs. the overhead of maintaing two syntaxes is too large https://github.com/opral/inlang-paraglide-js/issues/329
await compile({
- experimentalEmitTs: true,
})
2.0.0-beta.11
- improve: compiler awaits ongoing compilations before starting a new one
- update dependency that fixes https://github.com/opral/inlang-paraglide-js/issues/320
2.0.0-beta.10
- remove
availableprefix from locale APIs alltogether https://github.com/opral/inlang-paraglide-js/issues/201#issuecomment-2596202820
2.0.0-beta.9
- Expose compiler on the index
-import { compile } from "@inlang/paraglide-js/compiler";
+import { compile } from "@inlang/paraglide-js";
- expose paraglide compile args
+ import { type CompileArgs } from "@inlang/paraglide-js";
2.0.0-beta.8
- rename
runtime.localestoruntime.availableLocalesto align with v1 API and avoid ambiguity https://github.com/opral/inlang-paraglide-js/issues/314 - remove legacy
languageTagAPIs https://github.com/opral/inlang-paraglide-js/issues/315
2.0.0-beta.7
- fixed windows path problems
- increased performance of the compiler by removing a redundant setTimeout
- increased performance of the compiler by removing prettier
experimentalEmitTsflag
2.0.0-beta.3
Patch Changes
- remove
fast-globas dependency in favor of node's built-infs.glob(a new API in node 22)
2.0.0
Major changes
- Upgrade to @inlang/sdk v2
- Support for variants (pluralization, gendering, A/B test, etc.)
Minor Changes
-
1d62451: remove
dedentdependency in CLI -
5d906bd: refactor: remove posthog-node dependency
Posthog node has been replaced for a fetch call. Removing 3 (posthog + 2 transitive dependencies).
-
855a71c: adds
experimentalEmitTsDeclarationscompiler option https://github.com/opral/inlang-paraglide-js/issues/288await compile({ // ... options: { + experimentalEmitTsDeclarations: true } })Projects can now select if TypeScript declaration file should be emitted. The need for the
allowJs: trueoption in TypeScript configs becomes redundant at the cost of slower compilation times (https://github.com/opral/inlang-paraglide-js/issues/238). -
346c21b: maintenance: remove path prop from tsconfig
-"paths": { - "~/*": ["./src/*"] -}So not worth it "nice to have" "but it's better DX" thing. Breaks path resolving in JS. Vitest needed a vite config to resolve the paths because only TS knew how to resolve thep paths. Etc. Etc. Etc.
-
fb06546: adds
emitGitIgnoreandemitPrettierIgnorecompiler optionsCloses https://github.com/opral/inlang-paraglide-js/issues/189
await compile({ // ... options: { + emitPrettierIgnore: false + emitGitIgnore: false } }) -
e2b9e24: feat: expose compiler as library
closes https://github.com/opral/inlang-paraglide-js/issues/206
The Paraglide compiler is now exposed as a library. This allows you to use and extend the compiler however you need.
import { compile } from "@inlang/paraglide-js/compiler"; await compile({ path: "/path/to/project.inlang", outdir: "/path/to/output", }); -
44ac447: maintenance: remove vite in favor of tsc to build paraglide js lib
Closes https://github.com/opral/inlang-paraglide-js/issues/208
- "build": "vite build", + "build": "tsc",Paraglide JS used vite to build the library. This change removes vite in favor of tsc to build the library. This change is made to simplify the build process and to make it easier to maintain the library in the future.
1.11.2
Patch Changes
- 59c8b11: Fix Ninja recommendation and adoption if working directory is not the repo root
1.11.1
Patch Changes
-
14d80b3: Removed the "Which tech-stack are you using?" prompt from the
initcommand as it was not providing any real value. All it did was link you to the appropriate documentation.From now on we rely on the docuemntation site to guide people to the correct documenation for their framework.
- SvelteKit: https://inlang.com/m/dxnzrydw/paraglide-sveltekit-i18n
- NextJs: https://inlang.com/m/osslbuzt/paraglide-next-i18n
- Astro: https://inlang.com/m/iljlwzfs/paraglide-astro-i18n
- SolidStart: https://inlang.com/m/n860p17j/paraglide-solidstart-i18n
- Vite: https://github.com/opral/monorepo/tree/main/inlang/packages/paraglide/paraglide-vite
1.11.0
Minor Changes
- e37eabf: - renamed packages
@inlang/cross-sell-Xto@inlang/recommend-Xbe more descriptive- refactor recommendation view in Sherlock VS Code extension
- introduce new
shouldRecommendfunction to@inlang/recommend-sherlock&@inlang/recommend-ninja
1.10.1
Patch Changes
- c5d145d: use types from SDK for error handling
1.10.0
Minor Changes
- 33662e6: Gracefully handle errors in the Inlang Project. Only crash on errors that are fatal to paraglide specifically
1.9.1
Patch Changes
- b8573fa: Improved error-reporting
1.9.0
Minor Changes
- eb941fe: Prompt about adding the Ninja Github Action for translation-linting during
paraglide-js init. Also exposes it over the internal API.
Patch Changes
- 9566348: Better handling of
tsconfigfiles thatextendsanother config.
1.8.0
Minor Changes
- 21ab0a0: Add an output mode where each message is it's own file. This enables treeshaking in less capable bundlers. Currently this is only available via the programmatic API.
Patch Changes
- 21ab0a0: performance improvements
1.7.3
Patch Changes
- 32cbe48: Improve
bestMatchreliability
1.7.2
Patch Changes
- 6105a50: No longer log "Exiting the Watcher" when stopping the watching process, as it was causing annoying CMD popups on windows
1.7.1
Patch Changes
- 4d24188:
paraglide-js initnow uses thecreateNewProjectAPI from@inlang/sdkfor creating new projects. This resulits in higher reliability.
1.7.0
Minor Changes
- 0774c1a: Expose CLI programmatically to enable framework-specific init clis
1.6.2
Patch Changes
- cee4692: Use index accesses instead of
.atfunction for better compatability with legacy browsers - 4b631aa: Update invalid type-declarations
- 3c7a87c: Fixes a race-condition when creating the messages directory during
paraglide-js init - ab1fe48: When initialising and a single project is available, it no longer suggests and empty string as the project path
1.6.1
Patch Changes
- fa6aa31: Update internal adapter-utilities
- dee5aa6: Add
--silentoption toparaglide-js compilecommand that will only log errors
1.6.0
Minor Changes
- 462325b: Paraglide now ships with internal utility functions that handle common adapter tasks such as language-negotiation. These aren't public facing, but the version bump is required to make sure adapter-packages resolve the correct version of paragldie.
1.5.0
Minor Changes
- 2428451:
paraglide-js initnow finds more existing projects
1.4.0
Minor Changes
- d47b2aa: Generate empty
messages/{lang}.jsfiles if no messages are present. This way the "shape" of the generated output is always the same regardless of messages
Patch Changes
- 192fdec: prompt the user for the
outdirduringparaglide-js init - 0b7c82e: Inline package-version at build time to be more robust
1.3.7
Patch Changes
- 1cc9cbc: Run compiler after
paraglide-js initso that initial files are present - 5401f95: Add
--outdirflag to the generated CLI commands
1.3.6
Patch Changes
- 526b0ba:
paraglide-js initnow prompts for which languages should be supported - 26d2ba1: No longer add
identical-patternlint rule by default
1.3.5
Patch Changes
- 7dce581: fix
openRepositorycrash in non-git environments
1.3.4
Patch Changes
- 2a42b6e: bump
@lix-js/clientdependency
1.3.3
Patch Changes
- 11f0e18: Update dependency
- 10e3c28: fix JSDoc annotations on message aliases
1.3.2
Patch Changes
- 45975c0: Fail gracefully if adding
.vscodefolder fails
1.3.1
Patch Changes
- afaaffa: Bundle
@inlang/recommend-sherlock. This is used to promot once duringparaglide-js initto ask if you want to install the Sherlock vscode extension
1.3.0
Minor Changes
- 4970afc: paraglide deprecate aliases
- 4837297: File locking for concurrent message updates through the load/store plugin api Auto-generated human-IDs and aliases - only with experimental: { aliases: true }
Patch Changes
- @inlang/recommend-sherlock@0.0.2
1.2.9
Patch Changes
- a99e35fee: use
@inlang/recommend-sherlockduring vscode extension initialization - Updated dependencies [a99e35fee]
- @inlang/recommend-sherlock@0.0.2
1.2.8
Patch Changes
- b0f1e908b: Prompt user for tech-stack when running
paraglide-js init& recommend Adapters
1.2.7
Patch Changes
- f6ec6cdc9: bump
@inlang/sdkdependency
1.2.6
Patch Changes
- 960f8fb70: rename the vscode extension to "Sherlock"
1.2.5
Patch Changes
- 00f181ad3: fix broken dependency
1.2.4
Patch Changes
- Updated dependencies [244442698]
- @inlang/language-tag@1.5.0
1.2.3
Patch Changes
- 4c26fa70a: bump dependencies
1.2.2
Patch Changes
- 613ef9877: fix: Bump
@lix-js/clientdependency
1.2.1
Patch Changes
- 74dc1f8c6: Update dependencies
- 4ae6295d0: Detect when
paraglide-js initis being run inside the VsCode terminal and skip the VsCode question if so - Updated dependencies [74ac11c47]
- @inlang/language-tag@1.4.0
1.2.0
Minor Changes
- 0f0e8496d: Throw runtime error if
languageTag()returns a non-language tag value
1.1.1
Patch Changes
- 7ea9753fb: Improve onboarding message
- 4277232db: fix: better formatting of messageID fallbacks
1.1.0
Minor Changes
- cd29edb11: bumbing fixed env var dependecy issue affected packages
1.0.0
Bump Version to 1.0 as no more breaking changes are expected.
1.0.0-prerelease.26
Hotfix: Bundle SDK
1.0.0-prerelease.25
Update dependencies
1.0.0-prerelease.24
feat: Support language Fallbacks according to BCP 47 specification
1.0.0-prerelease.23
Update dependencies
1.0.0-prerelease.22
Update dependencies
1.0.0-prerelease.21
feat: Handle variables that have invalid JS identifiers as names. fix: Better text escaping in the compiler. fix: Compiler now fails reliably when a message ID is an invalid JS identifier.
1.0.0-prerelease.20
Paraglide now checks if the messages have actually changed before recompiling. This should improve reliability and performance.
1.0.0-prerelease.19
fix: Fix inlang/internal#195
1.0.0-prerelease.18
paraglide-js init now adds @inlang/message-lint-rule-valid-js-identifier by default.
1.0.0-prerelease.17
paraglide-js init now adds paraglide-js compile to the postinstall script by default. This sidesteps numerous linting issues when using paraglide in CI environments.
1.0.0-prerelease.16
Fix paraglide-js compile hanging for a couple seconds after successful compilation
1.0.0-prerelease.15
Fix crash when using npx @inlang/paraglide-js init and selecting vscode.
1.0.0-prerelease.14
Added --watch flag to the paraglide-js compile command. This will keep the process alive and recompile whenever messages are changed.
paraglide-js compile --project ./project.inlang --watch
1.0.0-prerelease.13
./paraglide/runtime.js now exports a function called isAvailableLanguageTag. This is
the recommended way to check if something is a valid language tag, while maintaining
type safety.
//Pseudo code
import { isAvailableLanguageTag } from "./paraglide/runtime";
if (isAvailableLanguageTag(params.lang)) {
return renderSite(params.lang);
} else {
return 404;
}
1.0.0-prerelease.12
[Internal Change] Expose the compiler so that bundler plugins can call it programmatically instead of going through the CLI.
1.0.0-prerelease.11
onSetLanguageTag no longer throws when called multiple times. Newer callbacks will overwrite old ones.
Developers still should not call onSetLanguageTag multiple times, this is needed for HMR to work reliably.
Big thanks to @KraXen72 for helping us find this bug.
1.0.0-prerelease.10
Add an optional options argument to message functions, to allow forcing a languageTag regardless of which languageTag is currently set.
import * as m from "./paraglide/messages";
const msg = m.hello({ name: "John" }, { languageTag: "de" });
1.0.0-prerelease.9
The paraglide-js init command now uses the inlang message format 2.0 which is human readable.
1.0.0-prerelease.8
IMPROVE: Paraglide now splits messages into different resource files as a step towards splitting messages by language via a bundler plugin.
import * as en from "./paraglide/messages/en";
import * as de from "./paraglide/messages/de";
en.hello();
de.hello();
1.0.0-prerelease.7
FIX: type error https://github.com/opral/monorepo/pull/1610#issuecomment-1801768825
export const currentLanguageTag = (params) => {
+ /** @type {Record<string, string>} */
const variants = {
en: `The current language tag is "${params.languageTag}".`,
de: `Der aktuelle Sprachtag ist "${params.languageTag}".`,
}
return variants[languageTag()] ?? "currentLanguageTag"
}
1.0.0-prerelease.6
BREAKING: Paraglide JS now compiles into source code, see https://github.com/opral/monorepo/issues/1607.
What you need to change:
- Remove
--namespacefrom the compile command - Replace imports from paraglide to point to the directory in ther source code:
-import { setLanguageTag, languageTag } from '@inlang/paraglide-js/sveltekit-example';
+import { setLanguageTag, languageTag } from '../../paraglide-js/runtime';
-import * as m from "@inlang/paraglide-js/sveltekit-example/messages"
+import * as m from "../../paraglide-js/messages"
1.0.0-prerelease.5
improve: paraglide-js init now adds the Visual Studio Code extension (Sherlock) if vscode is used
1.0.0-prerelease.4
add: paraglide-js init command which simplifies the setup process
1.0.0-prerelease.3
fix: https://github.com/opral/monorepo/issues/1478
1.0.0-prerelease.1
fix: Jetbrains based editors not detecting @inlang/paraglide-js/{namespace}/messages imports
The bug has been fixed by moving ./*/messages above the less specifc ./* export.
"exports": {
"./*/messages": "./dist/compiled-output/*/messages.js",
"./*": "./dist/compiled-output/*/runtime.js"
},

