Skip to main content

Crate intlayer_swc_plugin

Crate intlayer_swc_plugin 

Source
Expand description

§intlayer-swc-plugin

An SWC transform plugin for Intlayer that replaces useIntlayer / getIntlayer / useTranslations call arguments with pre-loaded dictionary imports at compile time, and rewrites content field accesses to the short aliases assigned by the minification pipeline.

§What it does

Given source code like:

import { useIntlayer } from "react-intlayer";
const t = useIntlayer("locale-switcher");

The plugin rewrites it to:

import _abc123 from "../../.intlayer/dictionaries/locale-switcher.json" with { type: "json" };
import { useDictionary as useIntlayer } from "react-intlayer";
const t = useIntlayer(_abc123);

This eliminates the runtime registry lookup and enables tree-shaking for per-locale bundles.

When the build.minify pipeline has renamed the compiled dictionary’s fields, the matching source accesses are rewritten too (content.title → content.a), driven by the fieldRenameMap option.

§Pipeline

Each file goes through, in order:

  1. field_rename – rewrite content field accesses to their short alias. Runs first because it keys off the dictionary key that step 3 erases.
  2. pre_pass – discover the local names of every recognised caller, the package each was imported from, and which of those packages resolve a dictionary to a dynamic/fetch loader.
  3. optimize – rewrite the call sites and import specifiers.
  4. imports – inject the dictionary imports the rewrite created.

§Compat adapters

Steps 2 and 3 recognise the base intlayer getters only. The compat adapters (@intlayer/react-i18next, @intlayer/next-intl, …) reach the plugin as extraCallers descriptors injected by their own bundler plugin, and every adapter-specific decision lives behind them:

  • extra_caller – matching a compat caller, resolving its namespace, and rewriting its call sites and import specifiers.

With no extraCallers configured, optimize holds no extra_caller::ExtraCallerContext at all, so none of that code runs and the base rewrite behaves exactly as if the adapters did not exist.

§Division of labour with the JavaScript side

Purging unused fields and assigning short aliases require reading every component source file and rewriting the compiled dictionary JSON — file I/O and cross-file state a per-file Wasm transform cannot do. That analysis runs on the JavaScript side (@intlayer/babel, invoked from withIntlayer), and its result reaches this crate as the fieldRenameMap option.

That option comes back empty when the visual editor is enabled — the editor resolves its edits by keyPath, which renaming would invalidate — so this crate then only rewrites call sites and imports. Purging is unaffected and happens on the JavaScript side either way.

§Usage as an SWC / Next.js Wasm plugin

The crate is distributed on npm as @intlayer/swc. Configure it in your next.config.*:

const nextConfig = {
  experimental: {
    swcPlugins: [["@intlayer/swc", { /* PluginConfig fields */ }]],
  },
};

§Usage as a native Rust library

Add to Cargo.toml:

[dependencies]
intlayer-swc-plugin = "7"

Then call process_transform directly:

use intlayer_swc_plugin::{PluginConfig, process_transform};
use swc_core::ecma::ast::Program;

fn my_transform(program: Program) -> Program {
    let config = PluginConfig {
        dictionaries_dir: "/project/.intlayer/dictionaries".into(),
        dictionaries_entry_path: "/project/.intlayer/dictionaries.mjs".into(),
        dynamic_dictionaries_dir: "/project/.intlayer/dynamic_dictionaries".into(),
        fetch_dictionaries_dir: "/project/.intlayer/fetch_dictionaries".into(),
        import_mode: Some("static".into()),
        replace_dictionary_entry: Some(false),
        ..PluginConfig::default()
    };
    process_transform(program, config, "/project/src/page.tsx".into())
}

Re-exports§

pub use config::ExtraCallerConfig;
pub use config::FieldRenameMap;
pub use config::FieldRenameNode;
pub use config::LogLevel;
pub use config::NamespaceOptionConfig;
pub use config::PluginConfig;
pub use paths::normalize_path;

Modules§

ast
Small, dependency-free helpers for reading and building the AST nodes the transforms care about.
config
Plugin configuration types.
dictionary_entry
Replacement of the generated dictionaries entry module.
dictionary_imports
The dictionary imports one file needs, accumulated while its call sites are rewritten and injected in one pass at the end.
extra_caller
Namespace resolution for compat-adapter callers (useTranslation, useI18n, useLingui, …) described by ExtraCallerConfig.
field_rename
Source-side counterpart of the build.minify pipeline.
imports
Injection of the dictionary import declarations collected by the optimize transform.
logger
Build-time reporting.
optimize
The optimize transform: replaces the dictionary-key argument of every recognised caller with a pre-imported dictionary object and re-points the import specifier at the matching *Dictionary helper.
packages
Package specifiers and generated-file conventions shared by the transforms.
paths
Path helpers used to build the module specifiers of the injected dictionary imports.
pre_pass
First traversal: discovers which local identifiers refer to an intlayer or compat-adapter caller, which package each was imported from, and which of those packages resolve a dictionary to a dynamic/fetch loader.

Functions§

process_transform
Applies the Intlayer SWC transform to program.