cloudflare-next-intl 0.10.33 → 0.10.34

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -284,7 +284,7 @@ export default defineConfig({
284
284
  5. **Locale File Bundling & Resolution (`localeFiles`)**: Resolves `@locale-file/*` to your `./messages` directory and transforms dynamic imports into `import.meta.glob('/messages/*.json', { eager: true })` for lightning-fast locale loading on Cloudflare Workers.
285
285
  6. **User-Agent Stub (`userAgentStub`)**: Prevents Next.js `user-agent` from importing `node:fs` during workerd runtime execution (which otherwise causes runtime 404 / 500 crashes in Workers proxy/middleware).
286
286
  7. **Cloudflare Workers Client Stub (`cfWorkersClientStub`)**: Stubs `cloudflare:workers` in client builds so shared modules can be referenced without client bundling errors.
287
- 8. **Build ID Asset Emission (`buildIdAsset`)**: Emits `BUILD_ID` static asset in the client build directory from `process.env.__VINEXT_SHARED_BUILD_ID` or `process.env.__VINEXT_BUILD_ID`.
287
+ 8. **Build ID Asset Emission (`buildIdAsset`)**: Emits the `BUILD_ID` static asset in the client build directory using Vite's `buildApp` hook (`order: "post"`). Resolves the ID from `process.env.__VINEXT_SHARED_BUILD_ID` or `process.env.__VINEXT_BUILD_ID`, falling back to reading `<serverOutDir>/BUILD_ID` (from `builder.environments.rsc`, `builder.environments.ssr`, or `dist/server/BUILD_ID`). If no ID is found, it generates a fallback timestamp ID and logs a warning, ensuring client output never misses `BUILD_ID`.
288
288
  9. **Vinext Route Wiring & Optimistic Prefetch Fix (`vinextRouteWiringFix`)**: ⚠️ Monkey-patches Vinext's compiled runtime on disk (`node_modules/vinext/dist/**`) — **on by default** since 0.9.51 via `experimentalRouteLoadingFixes` (also defaulting to on). Fixes route wiring (a route-specific `loading.tsx` losing to an ancestor/root skeleton), route matching and optimistic (client-side) routing for leading `:locale` segments, prefetch learning (an in-flight prefetch losing the race so the previous page stays on screen), and a `refresh()` navigation cancelling an in-flight page-to-page navigation because both share the same counter. Every sub-patch is regex-based against vinext's exact compiled shape and checks that the vinext-internal identifiers it relies on (`makeThenableParams`, `trieMatch`, `getPrefetchCache`, …) are still present before touching a file — a future vinext release that renames or removes one is left unpatched (with a console warning) rather than being patched into a broken half-state. Set `experimentalRouteLoadingFixes: false` (or `vinextRouteWiringFix: false`) to opt out entirely; see **Plugin Options** below for the individual sub-patch flags (`routeWiring`, `routeMatching`, `optimisticRouting`, `prefetchLearning`, `suspenseProbe`, `renderDependency`, `optimisticLearningTimeout`, `pageInvokerSuspensionRelease`, `refreshDeferral`, `unblockRenderDependencies`, `unblockPageElementDependencies`).
289
289
  10. **Layout DB Query Check (`layoutQueriesCheck`)**: Scans each `layout.tsx`/`layout.ts` and its reachable server-component import tree (also usable standalone from `cloudflare-next-intl/checkLayoutQueries`, or via the `cfni-check-layout-queries` CLI bin) for blocking `withUserDb()` / `withPublicDb()` calls. A layout re-renders on every route transition within its group, so a DB query anywhere in that tree blocks every page switch under it — the scan stops at Client Components (`'use client'`), which don't block server layout streaming. Prints a visible terminal warning with concrete fixes (move to a Client Component, wrap in `unstable_cache`, or move the query out of the shared layout into the page) by default; pass `{ strict: true }` to fail the build instead, or `false` to disable.
290
290
  12. **Firebase Auth Config Check (`firebaseAuthCheck`)**: Statically validates the `firebaseAuth` block of your `@intl-config` file on both `vite dev` and `vite build` (also usable standalone from `cloudflare-next-intl/checkFirebaseAuthConfig`). Errors on the fields nothing works without (`apiKey`, `authDomain`, `projectId`, `appId`, `redirectAuthPath`, `homePath`); warns when `appCheck` is present but server-side App Check minting can't run — `clientEmail`/`appId` plus **one** of `privateKey` or the full `oauthClientId`/`oauthClientSecret`/`oauthRefreshToken` triple — the misconfiguration whose only other symptom is a signed-in user rendering as signed-out on a cold navigation. Env-var-backed fields are resolved against `.env*` (Vite `loadEnv`, empty prefix) + `process.env`, so an unset `FIREBASE_SERVICE_ACCOUNT_*` secret is caught before deploy. Deliberately conservative: a value it can't evaluate (a call, an imported constant, a `??` fallback) counts as present. Prints a warning by default; pass `{ strict: true }` to fail the build, `false` to disable, or `appCheck.reportMissingServerCredentials: false` in your config to silence just the App Check warnings. No-op when there is no `firebaseAuth` block.
@@ -1,14 +1,31 @@
1
+ import { existsSync, readFileSync, writeFileSync, mkdirSync } from "node:fs";
2
+ import { resolve } from "node:path";
1
3
  export function buildIdAsset(fileName = "BUILD_ID") {
2
4
  return {
3
5
  name: "cfni:build-id-asset",
4
6
  apply: "build",
5
- generateBundle() {
6
- if (this.environment?.name !== "client")
7
- return;
8
- const buildId = process.env.__VINEXT_SHARED_BUILD_ID ?? process.env.__VINEXT_BUILD_ID;
9
- if (!buildId)
10
- return;
11
- this.emitFile({ type: "asset", fileName, source: buildId });
7
+ buildApp: {
8
+ order: "post",
9
+ async handler(builder) {
10
+ const client = builder.environments.client;
11
+ if (!client)
12
+ return;
13
+ const root = builder.config.root;
14
+ const serverDirs = [builder.environments.rsc, builder.environments.ssr]
15
+ .map((e) => e?.config.build.outDir)
16
+ .filter((d) => !!d)
17
+ .concat("dist/server")
18
+ .map((d) => resolve(root, d, "BUILD_ID"));
19
+ const fromFile = serverDirs.filter(existsSync).map((p) => readFileSync(p, "utf8").trim()).find(Boolean);
20
+ let buildId = process.env.__VINEXT_SHARED_BUILD_ID ?? process.env.__VINEXT_BUILD_ID ?? fromFile;
21
+ if (!buildId) {
22
+ buildId = String(Date.now());
23
+ builder.config.logger.warn(`[cfni:build-id-asset] build id not found; using generated ${buildId}`);
24
+ }
25
+ const outDir = resolve(root, client.config.build.outDir);
26
+ mkdirSync(outDir, { recursive: true });
27
+ writeFileSync(resolve(outDir, fileName), buildId);
28
+ },
12
29
  },
13
30
  };
14
31
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cloudflare-next-intl",
3
- "version": "0.10.33",
3
+ "version": "0.10.34",
4
4
  "description": "Optimized Next Intl Package Special for App Router and Cloudflare",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",