{"_id":"@ai-translate/next","_rev":"4-14687c0aca15ee34a12d57f422e9ff58","name":"@ai-translate/next","dist-tags":{"latest":"0.1.3"},"versions":{"0.1.0":{"name":"@ai-translate/next","version":"0.1.0","keywords":["i18n","l10n","internationalization","localization","translation","nextjs","next-intl","i18next","app-router","codegen"],"author":{"name":"Thiago Peres"},"license":"MIT","_id":"@ai-translate/next@0.1.0","maintainers":[{"name":"tperes","email":"hi@peres.pro"}],"homepage":"https://github.com/thiagoperes/ai-translate/tree/main/packages/ai-translate-next#readme","bugs":{"url":"https://github.com/thiagoperes/ai-translate/issues"},"dist":{"shasum":"7a61bdb5a74a22fc31245f6131b90ea76dc48fcf","tarball":"https://registry.npmjs.org/@ai-translate/next/-/next-0.1.0.tgz","fileCount":7,"integrity":"sha512-TozP30DOc5t8l4GoqgrSgQrc1PWFjOBprd3Wf8weUSLbYinhAcdlq1dkZHi+3tGa2mJw6+WEqZyEg9s0dL5f0w==","signatures":[{"sig":"MEUCIQCoUHrA73ijXrJr4gcWzwT/6uzFbEM3lzivYpq2k8lc2gIgeVt01ql1UlifXQRagmkUCTYL1TezLY7gCVw044VSJOQ=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@ai-translate%2fnext@0.1.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":66565},"main":"./dist/index.mjs","type":"module","_from":"file:ai-translate-next-0.1.0.tgz","types":"./dist/index.d.mts","engines":{"node":">=20.19.0"},"exports":{".":{"types":"./dist/index.d.mts","import":"./dist/index.mjs","default":"./dist/index.mjs"},"./package.json":"./package.json"},"scripts":{"lint":"oxlint -c ../../.oxlintrc.json --type-aware --deny-warnings src test vitest.config.ts tsdown.config.ts","test":"vitest run --config vitest.config.ts","build":"tsdown","coverage":"vitest run --config vitest.config.ts --coverage","test:pack":"publint . && attw --pack . --profile esm-only","typecheck":"tsc -p tsconfig.json --noEmit"},"_npmUser":{"name":"tperes","email":"hi@peres.pro"},"_resolved":"/tmp/f2eff777f43fc052dc46d8381e5ad6c9/ai-translate-next-0.1.0.tgz","_integrity":"sha512-TozP30DOc5t8l4GoqgrSgQrc1PWFjOBprd3Wf8weUSLbYinhAcdlq1dkZHi+3tGa2mJw6+WEqZyEg9s0dL5f0w==","repository":{"url":"git+https://github.com/thiagoperes/ai-translate.git","type":"git","directory":"packages/ai-translate-next"},"_npmVersion":"11.12.1","description":"Auto-discovery for Next.js localization setups: detects next-intl and i18next projects, infers locales and message layout, and generates an ai-translate config.","directories":{},"sideEffects":false,"_nodeVersion":"24.15.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/next_0.1.0_1787177669054_0.243756875301941","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@ai-translate/next","version":"0.1.1","keywords":["i18n","l10n","internationalization","localization","translation","nextjs","next-intl","i18next","app-router","codegen"],"author":{"name":"Thiago Peres"},"license":"MIT","_id":"@ai-translate/next@0.1.1","maintainers":[{"name":"tperes","email":"hi@peres.pro"}],"homepage":"https://github.com/thiagoperes/ai-translate/tree/main/packages/ai-translate-next#readme","bugs":{"url":"https://github.com/thiagoperes/ai-translate/issues"},"dist":{"shasum":"7f961289088f2015c23c9a1744a36c7aafa38fa6","tarball":"https://registry.npmjs.org/@ai-translate/next/-/next-0.1.1.tgz","fileCount":7,"integrity":"sha512-tv5m/gdVXIX+cZb5NWE9k1lJEjJHZIqUlEz6zNHauaTYarTqVOUFvI5rP5c4wMzPWe8fY3dPDTZ+/b7sTQI/rw==","signatures":[{"sig":"MEUCIE/h6iUGEIVua184OwqINRgE9F9oemviKykFgG5Tx0f5AiEAjwDeLPxGSz+W6soa5blNCfwKZLgH7C1YhIFzsBRPWNw=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":66565},"main":"./dist/index.mjs","type":"module","_from":"file:ai-translate-next-0.1.1.tgz","types":"./dist/index.d.mts","engines":{"node":">=20.19.0"},"exports":{".":{"types":"./dist/index.d.mts","import":"./dist/index.mjs","default":"./dist/index.mjs"},"./package.json":"./package.json"},"scripts":{"lint":"oxlint -c ../../.oxlintrc.json --type-aware --deny-warnings src test vitest.config.ts tsdown.config.ts","test":"vitest run --config vitest.config.ts","build":"tsdown","coverage":"vitest run --config vitest.config.ts --coverage","test:pack":"publint . && attw --pack . --profile esm-only","typecheck":"tsc -p tsconfig.json --noEmit"},"_npmUser":{"name":"tperes","email":"hi@peres.pro"},"_resolved":"/private/var/folders/0t/cw43w8gd5n583bgt4dcw1_cr0000gn/T/d6ac7622061841727d328c1a28da32ad/ai-translate-next-0.1.1.tgz","_integrity":"sha512-tv5m/gdVXIX+cZb5NWE9k1lJEjJHZIqUlEz6zNHauaTYarTqVOUFvI5rP5c4wMzPWe8fY3dPDTZ+/b7sTQI/rw==","repository":{"url":"git+https://github.com/thiagoperes/ai-translate.git","type":"git","directory":"packages/ai-translate-next"},"_npmVersion":"11.6.2","description":"Auto-discovery for Next.js localization setups: detects next-intl and i18next projects, infers locales and message layout, and generates an ai-translate config.","directories":{},"sideEffects":false,"_nodeVersion":"24.13.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/next_0.1.1_1787221938448_0.43753741843748917","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"name":"@ai-translate/next","version":"0.1.2","keywords":["i18n","l10n","internationalization","localization","translation","nextjs","next-intl","i18next","app-router","codegen"],"author":{"name":"Thiago Peres"},"license":"MIT","_id":"@ai-translate/next@0.1.2","maintainers":[{"name":"tperes","email":"hi@peres.pro"}],"homepage":"https://github.com/thiagoperes/ai-translate/tree/main/packages/ai-translate-next#readme","bugs":{"url":"https://github.com/thiagoperes/ai-translate/issues"},"dist":{"shasum":"5c20b06976099b6292e4714897a2e7b34624f9e1","tarball":"https://registry.npmjs.org/@ai-translate/next/-/next-0.1.2.tgz","fileCount":7,"integrity":"sha512-Oz0WueL0qjg6/fJR+QUPHzHoex4vY5fM96WSyad+DoYx+Mx6Oc8I375tTWdG2rLctiq3tf4eGCMVMavc5Vdv3w==","signatures":[{"sig":"MEUCIHbmgP3I3Ju7DzGCCL1yUkz6Ktn70KIpnSuqzzFHGB8/AiEA8X5+uEocx8EEyr1eki15v/3TUGa2R8V7kfUbY1/NtME=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEQCIHr4uUDfnrIh3o2veHjP9m5fLRQuH71U29sIngprFq0uAiA5BKyhupovDWr9aiQfd7zkHUChlYTRpg2jN1h1+vt7aA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@ai-translate%2fnext@0.1.2","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":45756},"main":"./dist/index.mjs","type":"module","_from":"file:ai-translate-next-0.1.2.tgz","types":"./dist/index.d.mts","engines":{"node":">=20.19.0"},"exports":{".":{"types":"./dist/index.d.mts","import":"./dist/index.mjs","default":"./dist/index.mjs"},"./package.json":"./package.json"},"scripts":{"lint":"oxlint -c ../../.oxlintrc.json --type-aware --deny-warnings src test vitest.config.ts tsdown.config.ts","test":"vitest run --config vitest.config.ts","build":"tsdown","coverage":"vitest run --config vitest.config.ts --coverage","test:pack":"publint . && attw --pack . --profile esm-only","typecheck":"tsc -p tsconfig.json --noEmit"},"_npmUser":{"name":"tperes","email":"hi@peres.pro"},"_resolved":"/tmp/688cfa3570edecdf4d8c9b233ac26702/ai-translate-next-0.1.2.tgz","_integrity":"sha512-Oz0WueL0qjg6/fJR+QUPHzHoex4vY5fM96WSyad+DoYx+Mx6Oc8I375tTWdG2rLctiq3tf4eGCMVMavc5Vdv3w==","repository":{"url":"git+https://github.com/thiagoperes/ai-translate.git","type":"git","directory":"packages/ai-translate-next"},"_npmVersion":"11.19.0","description":"Auto-discovery for Next.js localization setups: detects next-intl and i18next projects, infers locales and message layout, and generates an ai-translate config.","directories":{},"sideEffects":false,"_nodeVersion":"24.20.0","dependencies":{"@ai-translate/integrations":"0.1.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/next_0.1.2_1789906621045_0.8439780143472282","host":"s3://npm-registry-packages-npm-production"}},"0.1.3":{"_id":"@ai-translate/next@0.1.3","bugs":{"url":"https://github.com/thiagoperes/ai-translate/issues"},"dist":{"shasum":"bcf282b14674e3a9cf630d0d63865a81b17fc71a","tarball":"https://registry.npmjs.org/@ai-translate/next/-/next-0.1.3.tgz","fileCount":7,"integrity":"sha512-7fGnb8d0DfgFiLZyfsonS2MBU7/hTiNVActEA6zVmTkm4EXFDtZnT5u+9b9l5FYlXUD8o2z4z9zz4aLol1GV9g==","signatures":[{"sig":"MEUCIQDPyA9ZA+h8MECUW0H7OYddHBbfJg/M+FpCESgrcLF/dgIgW/HNbt9l58HbKknl03vdPyp0VvSt5rho9W/OhWLFz6M=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIA7nQjUrLKgtyA76/Ym/ugQAl3Qf3fK8Uq5HlUa02FGzAiEAjCVMAjwLqVx6pIj5pz5FoDL0izTVVpQecF1d45NLSts="}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@ai-translate%2fnext@0.1.3","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":45756},"main":"./dist/index.mjs","name":"@ai-translate/next","type":"module","_from":"file:ai-translate-next-0.1.3.tgz","types":"./dist/index.d.mts","author":{"name":"Thiago Peres"},"engines":{"node":">=20.19.0"},"exports":{".":{"types":"./dist/index.d.mts","import":"./dist/index.mjs","default":"./dist/index.mjs"},"./package.json":"./package.json"},"license":"MIT","scripts":{"lint":"oxlint -c ../../.oxlintrc.json --type-aware --deny-warnings src test vitest.config.ts tsdown.config.ts","test":"vitest run --config vitest.config.ts","build":"tsdown","coverage":"vitest run --config vitest.config.ts --coverage","test:pack":"publint . && attw --pack . --profile esm-only","typecheck":"tsc -p tsconfig.json --noEmit"},"version":"0.1.3","_npmUser":{"name":"tperes","email":"hi@peres.pro"},"homepage":"https://github.com/thiagoperes/ai-translate/tree/main/packages/ai-translate-next#readme","keywords":["i18n","l10n","internationalization","localization","translation","nextjs","next-intl","i18next","app-router","codegen"],"_resolved":"/tmp/6b5c8639fd3c3e4c93b75cb8740e8de2/ai-translate-next-0.1.3.tgz","_integrity":"sha512-7fGnb8d0DfgFiLZyfsonS2MBU7/hTiNVActEA6zVmTkm4EXFDtZnT5u+9b9l5FYlXUD8o2z4z9zz4aLol1GV9g==","repository":{"url":"git+https://github.com/thiagoperes/ai-translate.git","type":"git","directory":"packages/ai-translate-next"},"_npmVersion":"11.19.0","description":"Auto-discovery for Next.js localization setups: detects next-intl and i18next projects, infers locales and message layout, and generates an ai-translate config.","directories":{},"maintainers":[{"name":"tperes","email":"hi@peres.pro"}],"sideEffects":false,"_nodeVersion":"24.20.0","dependencies":{"@ai-translate/integrations":"0.2.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/next_0.1.3_1789928728288_0.2487671938258358"}}},"time":{"created":"2026-08-19T22:14:28.795Z","modified":"2026-09-20T18:25:28.753Z","0.1.0":"2026-08-19T22:14:29.204Z","0.1.1":"2026-08-20T10:32:18.649Z","0.1.2":"2026-09-20T12:17:01.137Z","0.1.3":"2026-09-20T18:25:28.388Z"},"bugs":{"url":"https://github.com/thiagoperes/ai-translate/issues"},"author":{"name":"Thiago Peres"},"license":"MIT","homepage":"https://github.com/thiagoperes/ai-translate/tree/main/packages/ai-translate-next#readme","keywords":["i18n","l10n","internationalization","localization","translation","nextjs","next-intl","i18next","app-router","codegen"],"repository":{"url":"git+https://github.com/thiagoperes/ai-translate.git","type":"git","directory":"packages/ai-translate-next"},"description":"Auto-discovery for Next.js localization setups: detects next-intl and i18next projects, infers locales and message layout, and generates an ai-translate config.","maintainers":[{"name":"tperes","email":"hi@peres.pro"}],"readme":"# @ai-translate/next\n\nAuto-discovery for Next.js localization setups. Given a project directory, it works out which i18n library is in use, where the messages live, which locales exist, and which one is the source — then renders an `ai-translate.config.ts` for it.\n\nThis supplies the Next.js and i18next detectors used by [`ai-translate init`](../ai-translate-cli#readme). Shared detection and rendering live in [`@ai-translate/integrations`](../ai-translate-integrations#readme); existing exports and default detectors from this package remain available. Use the neutral package to compose detectors for different platforms.\n\n## Install\n\n```bash\nnpm install @ai-translate/next\n```\n\n## Usage\n\n```ts\nimport { detectProject, renderConfig } from \"@ai-translate/next\";\n\nconst setups = await detectProject(process.cwd());\n\nfor (const setup of setups) {\n  console.log(setup.integrationId, setup.confidence);\n  for (const item of setup.evidence) {\n    console.log(`  ${item.detail} (${item.source})`);\n  }\n}\n\nif (setups[0]) {\n  console.log(renderConfig(setups[0].plan));\n}\n```\n\n`detectProject` returns every match, best first. A repository midway through a migration legitimately matches more than one.\n\n## What it recognises\n\n| Integration | Detected from | Message layout | Message format |\n| --- | --- | --- | --- |\n| `next-intl` | the `next-intl` dependency, `i18n/request.ts`, `i18n/routing.ts` | `messages/{locale}.json` or `messages/{locale}/{namespace}.json` | ICU |\n| `i18next` | `i18next`, `react-i18next`, or `next-i18next`, plus a settings module | `public/locales/{locale}/{namespace}.json` | i18next, with suffix-keyed plurals |\n\nBoth look under the project root and under `src/`. next-intl checks `messages`, `src/messages`, `locales`, and `src/locales`; i18next checks `public/locales`, `src/public/locales`, `locales`, `src/locales`, and `app/locales`, in that order. Namespace layouts require JSON files immediately inside the locale folder, matching the namespace adapter's scope. Empty placeholder folders do not hide a populated later root or a file-per-locale layout.\n\nAn inferred source must have a document in the selected layout. If the declared source is missing, detection checks later conventional roots instead of generating a config that would translate from a different language. Explicit target locales may still be missing on disk: sync can create them. Duplicate and non-locale declarations are filtered. If several populated layouts exist, the selected layout and alternatives appear in the plan's warnings; add separate catalogs when the project uses more than one.\n\n## Detection is read-only\n\nNothing is written and no project code is executed. Config modules are read as text and scanned for literal `locales` arrays and `defaultLocale` strings, never imported — importing a Next.js config would pull in plugins, environment access, and arbitrary side effects. Comments, quoted examples, and similarly named properties are ignored. Plain quoted literals, trailing commas, and `as const` are supported. Computed arrays, spreads, interpolation, escapes, conflicting declarations, and syntax outside this literal subset are not inferred; detection falls back to locale files and folders. This deliberately conservative scan does not resolve imports, custom runtime paths, or arbitrary JavaScript/TypeScript expressions. Configure these layouts explicitly.\n\nThat fallback is reported rather than hidden: the resulting plan carries a `warnings` entry, and `renderConfig` turns each warning into a `// TODO:` comment in the generated file.\n\n## Writing your own integration\n\nAn integration is a detector. It receives a read-only view of the project and either returns a plan or `null`.\n\n```ts\nimport { defineIntegration, detectProject } from \"@ai-translate/next\";\nimport type { Integration } from \"@ai-translate/next\";\n\nconst paraglide: Integration = defineIntegration({\n  async detect(context) {\n    const manifest = await context.packageJson();\n    if (manifest?.dependencies?.[\"@inlang/paraglide-js\"] === undefined) {\n      return null;\n    }\n\n    const locales = await context.listDirectories(\"messages\");\n    return {\n      confidence: 0.9,\n      displayName: \"Paraglide\",\n      evidence: [{ detail: \"Paraglide is a dependency\", source: \"package.json\" }],\n      integrationId: \"paraglide\",\n      plan: {\n        catalog: { kind: \"document-json\", rootDir: \"messages\" },\n        messageFormat: \"icu\",\n        sourceLocale: \"en\",\n        targetLocales: locales.filter((locale) => locale !== \"en\"),\n        warnings: [],\n      },\n    };\n  },\n  displayName: \"Paraglide\",\n  id: \"paraglide\",\n});\n\nconst setups = await detectProject(process.cwd(), { integrations: [paraglide] });\n```\n\nPassing `integrations` replaces the shipped set. `ai-translate init` accepts the same option.\n\nConfidence only ranks candidates. Keep it below `1` unless the evidence is conclusive, and reserve the high end for cases where both a dependency and a recognised message layout are present — a dependency alone is not enough, since a project can depend on a library it no longer uses.\n\n## License\n\nMIT\n","readmeFilename":"README.md"}