Browse docs

Core

Quickstart

ReactVanilla

Eight steps from empty Vite app to first translated string — no framework required. Each step links the page that owns the detail.

1. Install

pnpm add @secundus-studio/stift-core@0.4.0 @secundus-studio/stift-vite-plugin@0.4.0

Package variants: Installation.

2. Wire the Vite plugin

// vite.config.ts
import { stiftPlugin } from '@secundus-studio/stift-vite-plugin'

export default defineConfig({
  plugins: [stiftPlugin()],
})

Full options: Build: Vite Plugin & CLI.

3. Write the config

// stift.config.ts
import { defineConfig } from '@secundus-studio/stift-generator'

export default defineConfig({
  locales: { default: 'en', supported: ['en', 'ar'] },
  namespaces: { dir: 'locales', discovery: 'convention', default: ['common'] },
  messageFormat: 'icu-mf1',
  detection: { order: ['explicit', 'custom', 'navigator'], fallback: 'en' },
  loadingStrategy: 'lazy-per-namespace',
})

Start minimal; add params.context, units, and security.tier once the feature calls for them. Full schema: stift.config.ts.

4. Add the first namespace

Create locales/en/common.json:

{ "greeting": "Hello, {name}!" }

The default locale is the schema — new keys propagate to every other locale automatically. Never hand-sync locale files. Rules: Messages & Keys.

5. Create the instance

// src/stift.ts
import { createStift } from '@secundus-studio/stift-core'
import { createStiftRuntime } from 'virtual:stift/runtime'

export const stift = createStift({
  ...createStiftRuntime(), // generated config + catalog + source
})

The persisted locale + setParam/setUnit overrides are configured in stift.config.ts (state: { prefix: '__stift_', storage: 'webStorage' }) and read synchronously at construction. Generated artifacts: Build: Vite Plugin & CLI.

6. Boot

import { stift } from './stift'

const locale = await stift.detectLocale() // persisted > navigator > fallback
stift.setLocale(locale)
await stift.initialize({ locale }) // loads per loadingStrategy

7. Translate

Stift.scope('common')('greeting', { name: user.name })

Typos and wrong params are compile errors once the typegen runs. Values, plurals, formatting: Translating & Formatting.

8. Verify

  • pnpm dev: the greeting renders from locales/en/common.json.
  • Mistype a key: tsc fails. That is the whole point.

Where next?