[GH-ISSUE #751] Build fails with Unexpected token in layout.tsx (default create-next-app next/font/google) #163

Closed
opened 2026-05-06 12:37:47 +02:00 by BreizhHardware · 3 comments

Originally created by @kingRayhan on GitHub (Apr 2, 2026).
Original GitHub issue: https://github.com/cloudflare/vinext/issues/751

Description

vinext build fails on a stock create-next-app App Router project whose root app/layout.tsx uses next/font/google (Geist and Geist_Mono with subsets: ["latin"]). This is the default scaffold many users start from, so the failure blocks a straightforward migration to vinext.

Reproduction

Repository: https://github.com/kingRayhan/vinext-poc

git clone https://github.com/kingRayhan/vinext-poc.git
cd vinext-poc
bun install
bun run build

Actual behavior

Build fails during [1/5] analyze client references... with:

[builtin:vite-transform] Error: Unexpected token
 -  in app/layout.tsx at 234..235

(The reported span lines up with the second Geist_Mono({ ... }) call in the default layout.)

Expected behavior

vinext build completes successfully, matching the documented support for next/font/google (CDN / runtime loading per README).

Environment

  • vinext ^0.0.38
  • vite ^8.0.3
  • @vitejs/plugin-rsc ^0.5.21
  • react / react-dom 19.2.4

Suspected cause (optional)

The vinext:google-fonts build transform that injects _selfHostedCSS appears to insert , _selfHostedCSS before the closing } of the font options object. When the object uses a trailing comma after the last property (as create-next-app formats it), the result can contain a double comma (, ,), which would explain the parse error at the start of the injected property.

If that diagnosis is wrong, the repro repo should still be enough to trace the real failure in packages/vinext (e.g. plugins/fonts).

Originally created by @kingRayhan on GitHub (Apr 2, 2026). Original GitHub issue: https://github.com/cloudflare/vinext/issues/751 ### Description `vinext build` fails on a **stock create-next-app** App Router project whose root `app/layout.tsx` uses **`next/font/google`** (`Geist` and `Geist_Mono` with `subsets: ["latin"]`). This is the default scaffold many users start from, so the failure blocks a straightforward migration to vinext. ### Reproduction Repository: **https://github.com/kingRayhan/vinext-poc** ```bash git clone https://github.com/kingRayhan/vinext-poc.git cd vinext-poc bun install bun run build ``` ### Actual behavior Build fails during `[1/5] analyze client references...` with: ```text [builtin:vite-transform] Error: Unexpected token - in app/layout.tsx at 234..235 ``` (The reported span lines up with the second `Geist_Mono({ ... })` call in the default layout.) ### Expected behavior `vinext build` completes successfully, matching the documented support for `next/font/google` (CDN / runtime loading per README). ### Environment - `vinext` ^0.0.38 - `vite` ^8.0.3 - `@vitejs/plugin-rsc` ^0.5.21 - `react` / `react-dom` 19.2.4 ### Suspected cause (optional) The `vinext:google-fonts` build transform that injects `_selfHostedCSS` appears to insert `, _selfHostedCSS` before the closing `}` of the font options object. When the object uses a **trailing comma** after the last property (as create-next-app formats it), the result can contain a **double comma** (`, ,`), which would explain the parse error at the start of the injected property. If that diagnosis is wrong, the repro repo should still be enough to trace the real failure in `packages/vinext` (e.g. `plugins/fonts`).
Author
Owner

@kingRayhan commented on GitHub (Apr 2, 2026):

Confirmed on our side: removing next/font/google from app/layout.tsx makes vinext build succeed (same project otherwise unchanged). That matches the idea that the failure is in the Google Fonts build transform rather than the rest of the layout/metadata setup.

We dropped the Geist / Geist_Mono helpers and inlined plain className / CSS (or system fonts) as a temporary workaround until this is fixed upstream.

<!-- gh-comment-id:4174814354 --> @kingRayhan commented on GitHub (Apr 2, 2026): Confirmed on our side: **removing `next/font/google` from `app/layout.tsx` makes `vinext build` succeed** (same project otherwise unchanged). That matches the idea that the failure is in the Google Fonts build transform rather than the rest of the layout/metadata setup. We dropped the `Geist` / `Geist_Mono` helpers and inlined plain `className` / CSS (or system fonts) as a temporary workaround until this is fixed upstream.
Author
Owner

@james-elicx commented on GitHub (Apr 2, 2026):

Can you try with the new release please (v0.0.39) and see if that resolves the problem? I believe this is the same issue that was fixed by #719.

<!-- gh-comment-id:4176116572 --> @james-elicx commented on GitHub (Apr 2, 2026): Can you try with the new release please (v0.0.39) and see if that resolves the problem? I believe this is the same issue that was fixed by #719.
Author
Owner

@DenyVeyten commented on GitHub (Apr 4, 2026):

Still happens for me on vinext v0.0.39

The issue happens because Vite enforces strict ES module checking at build time. While vinext uses a Proxy on the default import to dynamically resolve any font requested, it doesn't explicitly declare named exports like Geist or Geist_Mono. This causes Rollup/Vite to throw the [MISSING_EXPORT] error when you try importing them by name.
To permanently fix this upstream issue locally, I have updated your scripts/patch-vinext.js to automatically inject the missing explicitly named exports directly into node_modules/vinext/dist/shims/font-google.js during the postinstall step.
The patch guarantees that these core Next.js fonts are correctly exported:

export const Geist = createFontLoader('Geist');
export const Geist_Mono = createFontLoader('Geist Mono');
export const Inter = createFontLoader('Inter');
<!-- gh-comment-id:4187004874 --> @DenyVeyten commented on GitHub (Apr 4, 2026): Still happens for me on vinext v0.0.39 > The issue happens because Vite enforces strict ES module checking at build time. While vinext uses a Proxy on the default import to dynamically resolve any font requested, it doesn't explicitly declare named exports like Geist or Geist_Mono. This causes Rollup/Vite to throw the [MISSING_EXPORT] error when you try importing them by name. To permanently fix this upstream issue locally, I have updated your scripts/patch-vinext.js to automatically inject the missing explicitly named exports directly into node_modules/vinext/dist/shims/font-google.js during the postinstall step. The patch guarantees that these core Next.js fonts are correctly exported: ```js export const Geist = createFontLoader('Geist'); export const Geist_Mono = createFontLoader('Geist Mono'); export const Inter = createFontLoader('Inter'); ```
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#163
No description provided.