Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -638,9 +638,7 @@ vinext({
cache: {
data: {
adapter: require.resolve("./my-adapter.js"),
options: {
/* … */
},
options: {/* … */},
},
},
});
Expand Down
4 changes: 1 addition & 3 deletions apps/web/next.config.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import type { NextConfig } from "next";

const nextConfig: NextConfig = {
/* config options here */
};
const nextConfig: NextConfig = {/* config options here */};

export default nextConfig;
4 changes: 4 additions & 0 deletions packages/vinext/src/server/app-ssr-entry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,10 @@ async function loadStaticPrerender(): Promise<StaticPrerender> {
try {
const [{ createRequire }, path] = await Promise.all([
import("node:module"),
// Native node:path is fine here: the resolved path is fed straight into
// a dynamic import() and never compared against pathslash-normalized
// ids, so forward-slash canonicalization buys nothing.
// oxlint-disable-next-line no-restricted-imports
import("node:path"),
]);
const require = createRequire(import.meta.url);
Expand Down
1,382 changes: 843 additions & 539 deletions pnpm-lock.yaml

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions pnpm-workspace.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,9 @@ catalog:
typescript: ^7.0.0
use-count-up: 3.0.1
validator: ^13.15.26
vite: npm:@voidzero-dev/vite-plus-core@0.2.2
vite: npm:@voidzero-dev/vite-plus-core@0.2.6
vite-plugin-commonjs: ^0.10.4
vite-plus: 0.2.2
vite-plus: 0.2.6
vitest: 4.1.9
web-vitals: ^4.2.4
wrangler: ^4.80.0
Expand Down
19 changes: 18 additions & 1 deletion tests/font-google-build.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,23 @@ async function buildFontGoogleMultipleFixture(): Promise<string> {
}
}

// Concatenate every emitted `.js` file under `dir`. The server build is
// code-split across `_next/static/*` chunks, so the transformed font output is
// no longer guaranteed to live in `index.js` alone — the markers can land in
// any chunk (e.g. the layout/page chunks).
async function readAllJs(dir: string): Promise<string> {
const entries = await fs.readdir(dir, { withFileTypes: true });
const parts = await Promise.all(
entries.map(async (entry) => {
const full = path.join(dir, entry.name);
if (entry.isDirectory()) return readAllJs(full);
if (entry.name.endsWith(".js")) return fs.readFile(full, "utf-8");
return "";
}),
);
return parts.join("\n");
}

describe("font-google build integration", () => {
let buildOutputPath: string;
let outDir: string;
Expand All @@ -82,7 +99,7 @@ describe("font-google build integration", () => {
buildOutputPath = await buildFontGoogleMultipleFixture();
outDir = path.dirname(path.dirname(buildOutputPath));

const content = await fs.readFile(buildOutputPath, "utf-8");
const content = await readAllJs(path.dirname(buildOutputPath));
expect(content).toContain("Geist");
expect(content).toContain("_vinext");
expect(content).toContain("selfHostedCSS");
Expand Down
82 changes: 41 additions & 41 deletions tests/nextjs-compat/TRACKING.md
Original file line number Diff line number Diff line change
Expand Up @@ -187,39 +187,39 @@ Ported from: https://github.com/vercel/next.js/tree/canary/test/e2e/app-dir
**Local**: `tests/nextjs-compat/metadata.test.ts`
**Fixtures**: `fixtures/app-basic/app/nextjs-compat/metadata-*`

| # | Next.js Test | Vinext Status | Notes |
| # | Next.js Test | Vinext Status | Notes |
| ----- | ------------------------------------------ | ------------- | -------------------------------------------------------------------- | ----------------------------------- |
| 1 | Title in head | PASS | `<title>this is the page title</title>` |
| 2 | Description meta tag | PASS | |
| 3 | Title template from layout | PASS | `"%s | Layout"` template applied correctly |
| 4 | Title template to child page | PASS | `"Extra Page | Layout"` |
| 5 | Generator meta tag | PASS | |
| 6 | Application-name meta tag | PASS | |
| 7 | Referrer meta tag | PASS | |
| 8 | Keywords meta tag | PASS | Joins with ", " (space after comma) vs Next.js "," — both valid |
| 9 | Author meta tags | PASS | Multiple author tags rendered |
| 10 | Creator meta tag | PASS | |
| 11 | Publisher meta tag | PASS | |
| 12 | Robots meta tag | PASS | |
| 13 | Format-detection meta tag | PASS | |
| 14 | og:title | PASS | |
| 15 | og:description | PASS | |
| 16 | og:url | PASS | |
| 17 | og:site_name | PASS | |
| 18 | og:type | PASS | |
| 19 | og:image | PASS | |
| 20 | og:image:width/height | PASS | |
| 21 | twitter:card | PASS | |
| 22 | twitter:title | PASS | |
| 23 | twitter:description | PASS | |
| 24 | twitter:image | PASS | |
| 25 | Complex robots (noindex, googlebot) | PASS | |
| 26 | Googlebot meta tag | PASS | |
| 27 | Canonical link | PASS | |
| 28 | Hreflang alternate links | PASS | React renders as `hrefLang` (camelCase) |
| 29 | generateMetadata with params (title) | PASS | Dynamic slug resolved |
| 30 | generateMetadata with params (description) | PASS | |
| 31-45 | Various N/A tests | N/A (x15) | Browser-only (client nav), file-based images, HMR, cache dedup, etc. |
| 1 | Title in head | PASS | `<title>this is the page title</title>` |
| 2 | Description meta tag | PASS | |
| 3 | Title template from layout | PASS | `"%s | Layout"` template applied correctly |
| 4 | Title template to child page | PASS | `"Extra Page | Layout"` |
| 5 | Generator meta tag | PASS | |
| 6 | Application-name meta tag | PASS | |
| 7 | Referrer meta tag | PASS | |
| 8 | Keywords meta tag | PASS | Joins with ", " (space after comma) vs Next.js "," — both valid |
| 9 | Author meta tags | PASS | Multiple author tags rendered |
| 10 | Creator meta tag | PASS | |
| 11 | Publisher meta tag | PASS | |
| 12 | Robots meta tag | PASS | |
| 13 | Format-detection meta tag | PASS | |
| 14 | og:title | PASS | |
| 15 | og:description | PASS | |
| 16 | og:url | PASS | |
| 17 | og:site_name | PASS | |
| 18 | og:type | PASS | |
| 19 | og:image | PASS | |
| 20 | og:image:width/height | PASS | |
| 21 | twitter:card | PASS | |
| 22 | twitter:title | PASS | |
| 23 | twitter:description | PASS | |
| 24 | twitter:image | PASS | |
| 25 | Complex robots (noindex, googlebot) | PASS | |
| 26 | Googlebot meta tag | PASS | |
| 27 | Canonical link | PASS | |
| 28 | Hreflang alternate links | PASS | React renders as `hrefLang` (camelCase) |
| 29 | generateMetadata with params (title) | PASS | Dynamic slug resolved |
| 30 | generateMetadata with params (description) | PASS | |
| 31-45 | Various N/A tests | N/A (x15) | Browser-only (client nav), file-based images, HMR, cache dedup, etc. |

**Result: 30/30 pass, 0 skip, 15 N/A (browser-only, file-based images, HMR)**

Expand Down Expand Up @@ -318,16 +318,16 @@ Three Playwright spec files cover client-side behaviors that cannot be tested vi

**Local**: `tests/e2e/app-router/nextjs-compat/metadata.spec.ts`

| # | Test | Status | Notes |
| # | Test | Status | Notes |
| --- | -------------------------------------------------------- | ------ | --------------------------------------------------- | -------------------------- |
| 1 | document.title matches metadata export | PASS | `toHaveTitle("this is the page title")` |
| 2 | description meta tag is present in DOM | PASS | `meta[name="description"]` queried in browser |
| 3 | title template applies correctly | PASS | `"Page | Layout"` in document.title |
| 4 | title template applies to child page | PASS | `"Extra Page | Layout"` |
| 5 | OpenGraph meta tags present in DOM | PASS | og:title, og:description, og:type verified |
| 6 | Twitter card meta tags present in DOM | PASS | twitter:card, twitter:title verified |
| 7 | generateMetadata renders correct title for dynamic route | PASS | `"params - my-slug"` |
| 8 | title updates on client-side navigation | PASS | Link click -> document.title updates without reload |
| 1 | document.title matches metadata export | PASS | `toHaveTitle("this is the page title")` |
| 2 | description meta tag is present in DOM | PASS | `meta[name="description"]` queried in browser |
| 3 | title template applies correctly | PASS | `"Page | Layout"` in document.title |
| 4 | title template applies to child page | PASS | `"Extra Page | Layout"` |
| 5 | OpenGraph meta tags present in DOM | PASS | og:title, og:description, og:type verified |
| 6 | Twitter card meta tags present in DOM | PASS | twitter:card, twitter:title verified |
| 7 | generateMetadata renders correct title for dynamic route | PASS | `"params - my-slug"` |
| 8 | title updates on client-side navigation | PASS | Link click -> document.title updates without reload |

**Result: 8/8 pass, 0 skip**

Expand Down
Loading