[PR #366] [MERGED] feat(next-intl): auto-detect config without createNextIntlPlugin #514

Closed
opened 2026-05-06 13:08:29 +02:00 by BreizhHardware · 0 comments

📋 Pull Request Information

Original PR: https://github.com/cloudflare/vinext/pull/366
Author: @NathanDrake2406
Created: 3/9/2026
Status: Merged
Merged: 3/9/2026
Merged by: @james-elicx

Base: mainHead: feat/next-intl-auto-detect


📝 Commits (3)

  • e2c687c fix: resolve NEXT_DATA type conflict with next package types
  • 52bae0f feat(next-intl): auto-detect next-intl config without createNextIntlPlugin
  • b9292a0 fix: address review feedback

📊 Changes

10 files changed (+356 additions, -57 deletions)

View changed files

📝 packages/vinext/src/check.ts (+1 -1)
📝 packages/vinext/src/client/entry.ts (+2 -1)
packages/vinext/src/client/vinext-next-data.ts (+22 -0)
📝 packages/vinext/src/config/next-config.ts (+102 -8)
📝 packages/vinext/src/global.d.ts (+6 -36)
📝 packages/vinext/src/shims/link.tsx (+2 -1)
📝 pnpm-lock.yaml (+0 -3)
📝 tests/fixtures/ecosystem/next-intl/next.config.mjs (+2 -5)
📝 tests/fixtures/ecosystem/next-intl/package.json (+0 -1)
📝 tests/next-config.test.ts (+219 -1)

📄 Description

Summary

  • Auto-detect next-intl in project dependencies and register the next-intl/config alias automatically — no createNextIntlPlugin() wrapper needed
  • Probe i18n/request.{ts,tsx,js,jsx} then src/i18n/request.{ts,tsx,js,jsx}, matching next-intl's own discovery order
  • Explicit aliases from webpack/turbopack config take precedence over auto-detection
  • Add targeted warning when config loading fails due to next-intl/plugin, telling users the wrapper is unnecessary
  • Fix NEXT_DATA type conflict: next/dist/client/index.d.ts declares Window.__NEXT_DATA__: NEXT_DATA which conflicted with our inline type in global.d.ts

Closes #202

How it works

detectNextIntlConfig(root, resolved) runs at the end of resolveNextConfig() — even when raw config is null (no next.config file at all). It:

  1. Checks if next-intl/config alias already exists (explicit wins)
  2. Uses createRequire(root).resolve('next-intl') to check installation
  3. Probes for i18n/request.{ts,tsx,js,jsx} and src/i18n/request.{ts,tsx,js,jsx}
  4. If found, sets resolved.aliases["next-intl/config"] to the absolute path
  5. If trailingSlash is true, injects _next_intl_trailing_slash env var

Test plan

  • pnpm run typecheck — passes (0 errors)
  • pnpm run lint — passes (0 errors, 0 warnings)
  • pnpm test tests/next-config.test.ts — 38 tests pass (10 new for detection logic)
  • pnpm test tests/ecosystem.test.ts — next-intl fixture renders /en and /de SSR correctly WITHOUT next installed and WITHOUT createNextIntlPlugin
  • pnpm test tests/shims.test.ts — 576 tests pass (no regressions)

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/cloudflare/vinext/pull/366 **Author:** [@NathanDrake2406](https://github.com/NathanDrake2406) **Created:** 3/9/2026 **Status:** ✅ Merged **Merged:** 3/9/2026 **Merged by:** [@james-elicx](https://github.com/james-elicx) **Base:** `main` ← **Head:** `feat/next-intl-auto-detect` --- ### 📝 Commits (3) - [`e2c687c`](https://github.com/cloudflare/vinext/commit/e2c687c5fa27d33f7c029a9f997bbdf3f0e415e3) fix: resolve NEXT_DATA type conflict with next package types - [`52bae0f`](https://github.com/cloudflare/vinext/commit/52bae0f020af9d8c16402df60d1a8245d0c303ab) feat(next-intl): auto-detect next-intl config without createNextIntlPlugin - [`b9292a0`](https://github.com/cloudflare/vinext/commit/b9292a05aba0c6b246b380b809565c8945dc55e8) fix: address review feedback ### 📊 Changes **10 files changed** (+356 additions, -57 deletions) <details> <summary>View changed files</summary> 📝 `packages/vinext/src/check.ts` (+1 -1) 📝 `packages/vinext/src/client/entry.ts` (+2 -1) ➕ `packages/vinext/src/client/vinext-next-data.ts` (+22 -0) 📝 `packages/vinext/src/config/next-config.ts` (+102 -8) 📝 `packages/vinext/src/global.d.ts` (+6 -36) 📝 `packages/vinext/src/shims/link.tsx` (+2 -1) 📝 `pnpm-lock.yaml` (+0 -3) 📝 `tests/fixtures/ecosystem/next-intl/next.config.mjs` (+2 -5) 📝 `tests/fixtures/ecosystem/next-intl/package.json` (+0 -1) 📝 `tests/next-config.test.ts` (+219 -1) </details> ### 📄 Description ## Summary - Auto-detect `next-intl` in project dependencies and register the `next-intl/config` alias automatically — no `createNextIntlPlugin()` wrapper needed - Probe `i18n/request.{ts,tsx,js,jsx}` then `src/i18n/request.{ts,tsx,js,jsx}`, matching next-intl's own discovery order - Explicit aliases from webpack/turbopack config take precedence over auto-detection - Add targeted warning when config loading fails due to `next-intl/plugin`, telling users the wrapper is unnecessary - Fix `NEXT_DATA` type conflict: `next/dist/client/index.d.ts` declares `Window.__NEXT_DATA__: NEXT_DATA` which conflicted with our inline type in `global.d.ts` Closes #202 ## How it works `detectNextIntlConfig(root, resolved)` runs at the end of `resolveNextConfig()` — even when raw config is `null` (no `next.config` file at all). It: 1. Checks if `next-intl/config` alias already exists (explicit wins) 2. Uses `createRequire(root).resolve('next-intl')` to check installation 3. Probes for `i18n/request.{ts,tsx,js,jsx}` and `src/i18n/request.{ts,tsx,js,jsx}` 4. If found, sets `resolved.aliases["next-intl/config"]` to the absolute path 5. If `trailingSlash` is true, injects `_next_intl_trailing_slash` env var ## Test plan - [x] `pnpm run typecheck` — passes (0 errors) - [x] `pnpm run lint` — passes (0 errors, 0 warnings) - [x] `pnpm test tests/next-config.test.ts` — 38 tests pass (10 new for detection logic) - [x] `pnpm test tests/ecosystem.test.ts` — next-intl fixture renders `/en` and `/de` SSR correctly WITHOUT `next` installed and WITHOUT `createNextIntlPlugin` - [x] `pnpm test tests/shims.test.ts` — 576 tests pass (no regressions) --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
BreizhHardware 2026-05-06 13:08:29 +02:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/vinext#514
No description provided.