Skip to content

[pull] canary from vercel:canary #207

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Jul 19, 2025
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
2 changes: 1 addition & 1 deletion lerna.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,5 @@
"registry": "https://registry.npmjs.org/"
}
},
"version": "15.4.2-canary.8"
"version": "15.4.2-canary.9"
}
2 changes: 1 addition & 1 deletion packages/create-next-app/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "create-next-app",
"version": "15.4.2-canary.8",
"version": "15.4.2-canary.9",
"keywords": [
"react",
"next",
Expand Down
4 changes: 2 additions & 2 deletions packages/eslint-config-next/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "eslint-config-next",
"version": "15.4.2-canary.8",
"version": "15.4.2-canary.9",
"description": "ESLint configuration used by Next.js.",
"main": "index.js",
"license": "MIT",
Expand All @@ -10,7 +10,7 @@
},
"homepage": "https://nextjs.org/docs/app/api-reference/config/eslint",
"dependencies": {
"@next/eslint-plugin-next": "15.4.2-canary.8",
"@next/eslint-plugin-next": "15.4.2-canary.9",
"@rushstack/eslint-patch": "^1.10.3",
"@typescript-eslint/eslint-plugin": "^5.4.2 || ^6.0.0 || ^7.0.0 || ^8.0.0",
"@typescript-eslint/parser": "^5.4.2 || ^6.0.0 || ^7.0.0 || ^8.0.0",
Expand Down
2 changes: 1 addition & 1 deletion packages/eslint-plugin-internal/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@next/eslint-plugin-internal",
"private": true,
"version": "15.4.2-canary.8",
"version": "15.4.2-canary.9",
"description": "ESLint plugin for working on Next.js.",
"exports": {
".": "./src/eslint-plugin-internal.js"
Expand Down
2 changes: 1 addition & 1 deletion packages/eslint-plugin-next/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@next/eslint-plugin-next",
"version": "15.4.2-canary.8",
"version": "15.4.2-canary.9",
"description": "ESLint plugin for Next.js.",
"main": "dist/index.js",
"types": "dist/index.d.ts",
Expand Down
2 changes: 1 addition & 1 deletion packages/font/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@next/font",
"private": true,
"version": "15.4.2-canary.8",
"version": "15.4.2-canary.9",
"repository": {
"url": "vercel/next.js",
"directory": "packages/font"
Expand Down
2 changes: 1 addition & 1 deletion packages/next-bundle-analyzer/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@next/bundle-analyzer",
"version": "15.4.2-canary.8",
"version": "15.4.2-canary.9",
"main": "index.js",
"types": "index.d.ts",
"license": "MIT",
Expand Down
2 changes: 1 addition & 1 deletion packages/next-codemod/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@next/codemod",
"version": "15.4.2-canary.8",
"version": "15.4.2-canary.9",
"license": "MIT",
"repository": {
"type": "git",
Expand Down
2 changes: 1 addition & 1 deletion packages/next-env/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@next/env",
"version": "15.4.2-canary.8",
"version": "15.4.2-canary.9",
"keywords": [
"react",
"next",
Expand Down
2 changes: 1 addition & 1 deletion packages/next-mdx/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@next/mdx",
"version": "15.4.2-canary.8",
"version": "15.4.2-canary.9",
"main": "index.js",
"license": "MIT",
"repository": {
Expand Down
2 changes: 1 addition & 1 deletion packages/next-plugin-storybook/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@next/plugin-storybook",
"version": "15.4.2-canary.8",
"version": "15.4.2-canary.9",
"repository": {
"url": "vercel/next.js",
"directory": "packages/next-plugin-storybook"
Expand Down
2 changes: 1 addition & 1 deletion packages/next-polyfill-module/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@next/polyfill-module",
"version": "15.4.2-canary.8",
"version": "15.4.2-canary.9",
"description": "A standard library polyfill for ES Modules supporting browsers (Edge 16+, Firefox 60+, Chrome 61+, Safari 10.1+)",
"main": "dist/polyfill-module.js",
"license": "MIT",
Expand Down
2 changes: 1 addition & 1 deletion packages/next-polyfill-nomodule/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@next/polyfill-nomodule",
"version": "15.4.2-canary.8",
"version": "15.4.2-canary.9",
"description": "A polyfill for non-dead, nomodule browsers.",
"main": "dist/polyfill-nomodule.js",
"license": "MIT",
Expand Down
2 changes: 1 addition & 1 deletion packages/next-rspack/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "next-rspack",
"version": "15.4.2-canary.8",
"version": "15.4.2-canary.9",
"repository": {
"url": "vercel/next.js",
"directory": "packages/next-rspack"
Expand Down
2 changes: 1 addition & 1 deletion packages/next-swc/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@next/swc",
"version": "15.4.2-canary.8",
"version": "15.4.2-canary.9",
"private": true,
"files": [
"native/"
Expand Down
14 changes: 7 additions & 7 deletions packages/next/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "next",
"version": "15.4.2-canary.8",
"version": "15.4.2-canary.9",
"description": "The React Framework",
"main": "./dist/server/next.js",
"license": "MIT",
Expand Down Expand Up @@ -100,7 +100,7 @@
]
},
"dependencies": {
"@next/env": "15.4.2-canary.8",
"@next/env": "15.4.2-canary.9",
"@swc/helpers": "0.5.15",
"caniuse-lite": "^1.0.30001579",
"postcss": "8.4.31",
Expand Down Expand Up @@ -163,11 +163,11 @@
"@jest/types": "29.5.0",
"@mswjs/interceptors": "0.23.0",
"@napi-rs/triples": "1.2.0",
"@next/font": "15.4.2-canary.8",
"@next/polyfill-module": "15.4.2-canary.8",
"@next/polyfill-nomodule": "15.4.2-canary.8",
"@next/react-refresh-utils": "15.4.2-canary.8",
"@next/swc": "15.4.2-canary.8",
"@next/font": "15.4.2-canary.9",
"@next/polyfill-module": "15.4.2-canary.9",
"@next/polyfill-nomodule": "15.4.2-canary.9",
"@next/react-refresh-utils": "15.4.2-canary.9",
"@next/swc": "15.4.2-canary.9",
"@opentelemetry/api": "1.6.0",
"@playwright/test": "1.51.1",
"@rspack/core": "1.4.5",
Expand Down
38 changes: 36 additions & 2 deletions packages/next/src/build/templates/app-page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1075,6 +1075,16 @@ export async function handler(
// should also be the case for a resume request because it's completed
// as a server render (rather than a static render).
if (!didPostpone || minimalMode) {
// If we're in test mode, we should add a sentinel chunk to the response
// that's between the static and dynamic parts so we can compare the
// chunks and add assertions.
if (process.env.__NEXT_TEST_MODE && minimalMode && isRoutePPREnabled) {
// As we're in minimal mode, the static part would have already been
// streamed first. The only part that this streams is the dynamic part
// so we should FIRST stream the sentinel and THEN the dynamic part.
body.unshift(createPPRBoundarySentinel())
}

return sendRenderResult({
req,
res,
Expand All @@ -1093,7 +1103,7 @@ export async function handler(
if (isDebugStaticShell || isDebugDynamicAccesses) {
// Since we're not resuming the render, we need to at least add the
// closing body and html tags to create valid HTML.
body.chain(
body.push(
new ReadableStream({
start(controller) {
controller.enqueue(ENCODED_TAGS.CLOSED.BODY_AND_HTML)
Expand All @@ -1113,11 +1123,18 @@ export async function handler(
})
}

// If we're in test mode, we should add a sentinel chunk to the response
// that's between the static and dynamic parts so we can compare the
// chunks and add assertions.
if (process.env.__NEXT_TEST_MODE) {
body.push(createPPRBoundarySentinel())
}

// This request has postponed, so let's create a new transformer that the
// dynamic data can pipe to that will attach the dynamic data to the end
// of the response.
const transformer = new TransformStream<Uint8Array, Uint8Array>()
body.chain(transformer.readable)
body.push(transformer.readable)

// Perform the render again, but this time, provide the postponed state.
// We don't await because we want the result to start streaming now, and
Expand Down Expand Up @@ -1208,3 +1225,20 @@ export async function handler(
throw err
}
}

// TODO: omit this from production builds, only test builds should include it
/**
* Creates a readable stream that emits a PPR boundary sentinel.
*
* @returns A readable stream that emits a PPR boundary sentinel.
*/
function createPPRBoundarySentinel() {
return new ReadableStream({
start(controller) {
controller.enqueue(
new TextEncoder().encode('<!-- PPR_BOUNDARY_SENTINEL -->')
)
controller.close()
},
})
}
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ const Dialog: React.FC<DialogProps> = function Dialog({
ref={dialogRef}
tabIndex={-1}
data-nextjs-dialog
data-nextjs-scrollable-content
role={role}
aria-labelledby={ariaLabelledBy}
aria-describedby={ariaDescribedBy}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,36 +41,6 @@ export const styles = css`
outline: 0;
}

[data-nextjs-dialog],
[data-nextjs-dialog] * {
&::-webkit-scrollbar {
width: 6px;
height: 6px;
border-radius: 0 0 1rem 1rem;
margin-bottom: 1rem;
}

&::-webkit-scrollbar-button {
display: none;
}

&::-webkit-scrollbar-track {
border-radius: 0 0 1rem 1rem;
background-color: var(--color-background-100);
}

&::-webkit-scrollbar-thumb {
border-radius: 1rem;
background-color: var(--color-gray-500);
}
}

/* Place overflow: hidden on this so we can break out from [data-nextjs-dialog] */
[data-nextjs-dialog-sizer] {
overflow: hidden;
border-radius: inherit;
}

[data-nextjs-dialog-backdrop] {
opacity: 0;
transition: opacity var(--transition-duration) var(--timing-overlay);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
type DevToolsScale,
} from './preferences'
import { ShortcutRecorder } from './shortcut-recorder'
import { useRestartServer } from '../../error-overlay-toolbar/use-restart-server'

export function UserPreferences({
hide,
Expand Down Expand Up @@ -69,6 +70,7 @@ export function UserPreferencesBody({
scale: DevToolsScale
setScale: (value: DevToolsScale) => void
}) {
const { restartServer, isPending } = useRestartServer()
const [theme, setTheme] = useState(getInitialTheme())

const handleThemeChange = (e: React.ChangeEvent<HTMLSelectElement>) => {
Expand Down Expand Up @@ -105,21 +107,6 @@ export function UserPreferencesBody({
setScale(value)
}

function handleRestartDevServer(invalidatePersistentCache: boolean) {
let endpoint = '/__nextjs_restart_dev'

if (invalidatePersistentCache) {
endpoint = '/__nextjs_restart_dev?invalidatePersistentCache'
}

fetch(endpoint, {
method: 'POST',
}).then(() => {
// TODO: poll server status and reload when the server is back up.
// https://github.com/vercel/next.js/pull/80005
})
}

return (
<>
<h2 className="dev-tools-info-section-title">General</h2>
Expand Down Expand Up @@ -253,8 +240,9 @@ export function UserPreferencesBody({
data-restart-dev-server
className="action-button"
onClick={() =>
handleRestartDevServer(/*invalidatePersistentCache*/ false)
restartServer({ invalidatePersistentCache: false })
}
disabled={isPending}
>
<span>Restart</span>
</button>
Expand All @@ -279,8 +267,9 @@ export function UserPreferencesBody({
data-reset-bundler-cache
className="action-button"
onClick={() =>
handleRestartDevServer(/*invalidatePersistentCache*/ true)
restartServer({ invalidatePersistentCache: true })
}
disabled={isPending}
>
<span>Reset Cache</span>
</button>
Expand Down Expand Up @@ -408,6 +397,11 @@ export const DEV_TOOLS_INFO_USER_PREFERENCES_STYLES = css`
}
}

.preference-section button:disabled {
opacity: 0.6;
cursor: not-allowed;
}

:global(.icon) {
width: 18px;
height: 18px;
Expand Down
Loading
Loading