{"_id":"@altified/next","name":"@altified/next","dist-tags":{"latest":"0.4.3"},"versions":{"0.4.3":{"name":"@altified/next","version":"0.4.3","type":"module","types":"./types/index.d.ts","bin":{"altified":"bin/altified.mjs"},"exports":{".":"./src/index.js","./switcher":"./src/switcher.js","./proxy":"./src/proxy.js","./fetch":"./src/fetch.js","./axios":"./src/axios.js","./auto":{"react-server":"./src/auto.js","default":"./src/auto-client.js"},"./config":{"import":"./src/config.js","require":"./src/config.cjs"},"./loader":"./src/loader.cjs"},"scripts":{"test":"node --test src/*.test.js src/cli/*.test.js"},"peerDependencies":{"next":">=15","react":">=18"},"dependencies":{"@babel/core":"^7.29.7","@babel/parser":"^7.28.5","@babel/plugin-transform-react-jsx":"^7.29.7","@babel/plugin-transform-typescript":"^7.29.7","@babel/traverse":"^7.28.5","@babel/types":"^7.28.5","server-only":"^0.0.1"},"gitHead":"267b92cb9bcfe6c91557a1549a2c677fc6f7e2b2","description":"Server-first translation, locale routing, and a dashboard-controlled language switcher for Next.js App Router projects.","_id":"@altified/next@0.4.3","_nodeVersion":"22.22.1","_npmVersion":"9.2.0","dist":{"integrity":"sha512-09qmOBtCrGjCRfhLV2yC0PWw2TVY+5Aynw/lj89EF44XAaiui+d9erWsizvltN9Np1YaoVeF2MA9elDtigqSzA==","shasum":"cd2c19feabfeec5b5b1c12d60494f8dfac26e900","tarball":"https://registry.npmjs.org/@altified/next/-/next-0.4.3.tgz","fileCount":19,"unpackedSize":90371,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQDy1O20odCYF3jRYY6DuEmYZCNBK4p5BhymxMcvpk/FwAIhAL2zfTgUWYFL97PqLuuwOIJ9WG3yTZsz4YGk9tK9ntEK"}]},"_npmUser":{"name":"benedictowusu","email":"beneyjoy@gmail.com"},"directories":{},"maintainers":[{"name":"benedictowusu","email":"beneyjoy@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/next_0.4.3_1788772618438_0.22353239868854557"},"_hasShrinkwrap":false}},"time":{"created":"2026-09-07T09:16:58.078Z","0.4.3":"2026-09-07T09:16:58.568Z","modified":"2026-09-07T09:16:58.924Z"},"maintainers":[{"name":"benedictowusu","email":"beneyjoy@gmail.com"}],"description":"Server-first translation, locale routing, and a dashboard-controlled language switcher for Next.js App Router projects.","readme":"# @altified/next\n\nServer-first translation, locale routing, and a dashboard-controlled language\nswitcher for Next.js App Router projects.\n\n## Install and initialize\n\nRequires Next.js 15 or newer and React 18 or newer.\n\n```bash\npnpm add @altified/next\npnpm exec altified init\n```\n\nYou can use `npm install @altified/next` and `npx altified init` instead.\n\nThe initializer detects JavaScript or TypeScript and whether the project uses a\n`src` directory. For a Next.js project it:\n\n- adds the server-only environment placeholders to `.env.local`;\n- wraps the existing Next config with `withAltified`;\n- creates a server-only client in `lib/altified`;\n- creates the locale-routing `proxy` file.\n\nExisting generated files and environment values are preserved. Review the\nreported warning if an unusual Next config cannot be changed safely. The\ninitializer never inserts visual UI into your layout: place the language\nswitcher yourself wherever it belongs. Use `--force` only when you intentionally\nwant to replace generated files.\n\nFor a locally running Altified backend:\n\n```bash\npnpm exec altified init --local\n```\n\n## Dashboard setup\n\nIn the Altified dashboard, create or open the project, add its source and target\nlanguages, and copy the project ID and server secret into `.env.local`:\n\n```dotenv\nALTIFIED_SECRET_KEY=altified_...\nALTIFIED_PROJECT_ID=your-project-uuid\nALTIFIED_DEFAULT_LOCALE=en\n```\n\n`ALTIFIED_SECRET_KEY` is server-only. Never rename it to a `NEXT_PUBLIC_`\nvariable. Restart Next.js after changing `.env.local`.\n\nConfigure and publish the language switcher in the dashboard. The component\nloads that public configuration, so language order, labels, theme, and routing\nbehavior can be changed without replacing the component.\n\n## Automatic JSX translation\n\nThe Next config installed by `altified init` translates literal JSX text in\nserver and client components:\n\n```jsx\nexport default function Page({ product }) {\n  return (\n    <main>\n      <h1>Welcome to our website</h1>\n      <p>{product.name}</p>\n    </main>\n  );\n}\n```\n\n`Welcome to our website` receives a stable generated translation key and is\nresolved for the locale selected by the proxy. Expression values such as\n`{product.name}` are intentionally left unchanged. Client components beginning\nwith `\"use client\"` are rewritten too, using the browser-safe client entry point\r\nfrom `@altified/next/auto`.\n\nIf the secret is missing or the translation service is unavailable, the source\ntext is rendered. Generated keys use the source file path and literal position;\nmoving a literal or inserting an earlier literal can create a new key.\n\n\n## Translation coverage\n\nAltified uses layered coverage so different Next.js project styles can opt into the safest path for each kind of copy:\n\n- **Automatic JSX:** literal text in server-rendered JSX and files with `\"use client\"` is translated regardless of tag (`h1`, `p`, `button`, `span`, and similar). Dynamic expressions such as `{name}` are left unchanged.\n- **Client components:** rewritten client components use the browser-safe `@altified/next/auto` entry point. You can still use `AltifiedClientProvider` to preload a translations map from the server and avoid client-side loading flashes.\n- **Metadata/head:** use `altified.translatedMetadata()` inside `generateMetadata` for translated `title`, `description`, Open Graph, and Twitter text.\n- **Backend/API data:** translate explicitly by field name. Do not blindly translate whole response objects, because IDs, slugs, emails, prices, statuses, and user content can be damaged.\n\nClient component example:\n\n```jsx\n\"use client\";\n\nimport { AltifiedText } from \"@altified/next/auto\";\n\nexport function Header() {\n  return <nav><AltifiedText translationKey=\"nav.contact\" defaultValue=\"Contact\" /></nav>;\n}\n```\n\nWrap that client tree with translations loaded from a server component:\n\n```jsx\nimport { AltifiedClientProvider } from \"@altified/next/auto\";\nimport { altified } from \"@/lib/altified\";\n\nconst navCopy = await altified.resolve(locale, [\n  { key: \"nav.contact\", defaultValue: \"Contact\" },\n  { key: \"nav.pricing\", defaultValue: \"Pricing\" },\n]);\n\n<AltifiedClientProvider translations={navCopy}>\n  <Header />\n</AltifiedClientProvider>\n```\n\nMetadata example:\n\n```js\nexport async function generateMetadata({ params }) {\n  const { locale } = await params;\n  return altified.translatedMetadata({\n    locale,\n    path: \"/pricing\",\n    origin: \"https://example.com\",\n    locales: [\"en\", \"fr\"],\n    title: \"Pricing\",\n    description: \"Simple plans for teams.\",\n    openGraph: {\n      title: \"Pricing\",\n      description: \"Simple plans for teams.\",\n    },\n  });\n}\n```\n\n## Explicit and batched translation\n\nUse the generated server client when you need named keys, dynamic values, or a\nsingle batched request:\n\n```js\nimport { altified } from \"@/lib/altified\";\n\nconst copy = await altified.resolve(locale, [\n  { key: \"home.title\", defaultValue: \"Hello\" },\n  { key: \"home.subtitle\", defaultValue: \"Welcome to our website\" },\n]);\n```\n\nUse `altified.t(key, options)` for one explicit string. Use\n`altified.metadata()` inside `generateMetadata` to build canonical and reciprocal\nalternate-language URLs.\n\n## Language switcher and locale routing\n\nInitialization does not add a switcher to your UI. Import it in the header,\nnavigation, or other component where you want the control to appear:\n\n```jsx\nimport { AltifiedLanguageSwitcher } from \"@altified/next/switcher\";\n\n<AltifiedLanguageSwitcher\n  projectId={process.env.ALTIFIED_PROJECT_ID}\n  locale={locale}\n  apiUrl={process.env.ALTIFIED_API_URL}\n/>\n```\n\nThe switcher only fetches the project's published public configuration; it\ndoes not expose the server secret. Its options open directly below the control\non desktop and mobile.\n\nThe generated `proxy.js` or `proxy.ts` uses the same configuration:\n\n```js\nimport { createAltifiedProxy } from \"@altified/next/proxy\";\n\nexport const proxy = createAltifiedProxy({\n  projectId: process.env.ALTIFIED_PROJECT_ID,\n});\n\nexport const config = {\n  matcher: [\"/((?!api|_next/static|_next/image|favicon.ico|.*\\\\..*).*)\"],\n};\n```\n\nIt caches public routing configuration for five minutes, uses stale\nconfiguration when refresh fails, and falls back to `ALTIFIED_DEFAULT_LOCALE`\nbefore configuration has been loaded. It also remembers the visitor's selected\nlocale. For example, after selecting French, an ordinary internal link to\n`/terms` is redirected to `/fr/terms`, so existing Next.js `Link` components do\nnot need locale-specific href values. The switcher does not intercept global\nanchor clicks. Use transformed static links or `localizePath` for dynamic hrefs;\ndirect `window.location` assignments remain full browser navigations by design.\n\n\n## Forward locale to backend APIs\n\nIf your Next app calls a separate backend, use `altifiedFetch` in your shared API client so the active Altified locale is sent as `Accept-Language`.\n\n```js\nimport { altifiedFetch } from \"@altified/next/fetch\";\n\nconst response = await altifiedFetch(`${BACKEND_URL}/api/products/`, {\n  credentials: \"include\",\n});\n```\n\nIn client components, `altifiedFetch` detects the locale from the Altified cookie, the document language, or the locale prefix in the URL. In server components, pass the locale explicitly when you already have it:\n\n```js\nconst response = await altifiedFetch(`${BACKEND_URL}/api/products/`, {\n  locale,\n  cache: \"no-store\",\n});\n```\n\nThis is the recommended way to make a Django backend using `django_altified` receive the same locale as the current Next route.\\n\\nFor Axios, attach the interceptor to your shared Axios instance:\\n\\n```js\\nimport axios from \"axios\";\\nimport { altifiedAxiosInterceptor } from \"@altified/next/axios\";\\n\\nconst api = axios.create({\\n  baseURL: BACKEND_URL,\\n  withCredentials: true,\\n});\\n\\naltifiedAxiosInterceptor(api);\\n```\n\n## Production workflow\n\n1. Add source copy as server-rendered JSX literals or explicit named keys.\n2. Visit the pages in each configured locale so missing strings are registered\n   and translated.\n3. Review and edit translations in the Altified dashboard.\n4. Add glossary terms for product names, technical terms, or words whose\n   translation must stay consistent, then regenerate affected translations.\n5. Publish the translations and switcher configuration.\n6. Set `ALTIFIED_SECRET_KEY`, `ALTIFIED_PROJECT_ID`, and\n   `ALTIFIED_DEFAULT_LOCALE` in the production environment and deploy.\n\nA glossary tells the translation engine how specific terms should be\ntranslated—or that they must not be translated. It does not replace the\ntranslation editor: the editor controls a particular string, while a glossary\napplies terminology consistently across many strings and future translations.\n\r\n","readmeFilename":"README.md","_rev":"1-2988a22a863f1c495e9b263bda05a98e"}