diff --git a/.claude/skills/update-docs/SKILL.md b/.claude/skills/update-docs/SKILL.md new file mode 100644 index 0000000000000..638e020b8dd36 --- /dev/null +++ b/.claude/skills/update-docs/SKILL.md @@ -0,0 +1,264 @@ +--- +name: update-docs +description: This skill should be used when the user asks to "update documentation for my changes", "check docs for this PR", "what docs need updating", "sync docs with code", "scaffold docs for this feature", "document this feature", "review docs completeness", "add docs for this change", "what documentation is affected", "docs impact", or mentions "docs/", "docs/01-app", "docs/02-pages", "MDX", "documentation update", "API reference", ".mdx files". Provides guided workflow for updating Next.js documentation based on code changes. +--- + +# Next.js Documentation Updater + +Guides you through updating Next.js documentation based on code changes on the active branch. Designed for maintainers reviewing PRs for documentation completeness. + +## Quick Start + +1. **Analyze changes**: Run `git diff canary...HEAD --stat` to see what files changed +2. **Identify affected docs**: Map changed source files to documentation paths +3. **Review each doc**: Walk through updates with user confirmation +4. **Validate**: Run `pnpm lint` to check formatting +5. **Commit**: Stage documentation changes + +## Workflow: Analyze Code Changes + +### Step 1: Get the diff + +```bash +# See all changed files on this branch +git diff canary...HEAD --stat + +# See changes in specific areas +git diff canary...HEAD -- packages/next/src/ +``` + +### Step 2: Identify documentation-relevant changes + +Look for changes in these areas: + +| Source Path | Likely Doc Impact | +| -------------------------------------- | --------------------------- | +| `packages/next/src/client/components/` | Component API reference | +| `packages/next/src/server/` | Function API reference | +| `packages/next/src/shared/lib/` | Varies by export | +| `packages/next/src/build/` | Configuration or build docs | +| `packages/next/src/lib/` | Various features | + +### Step 3: Map to documentation files + +Use the code-to-docs mapping in `references/CODE-TO-DOCS-MAPPING.md` to find corresponding documentation files. + +Example mappings: + +- `src/client/components/image.tsx` → `docs/01-app/03-api-reference/02-components/image.mdx` +- `src/server/config-shared.ts` → `docs/01-app/03-api-reference/05-config/` + +## Workflow: Update Existing Documentation + +### Step 1: Read the current documentation + +Before making changes, read the existing doc to understand: + +- Current structure and sections +- Frontmatter fields in use +- Whether it uses `` / `` for router-specific content + +### Step 2: Identify what needs updating + +Common updates include: + +- **New props/options**: Add to the props table and create a section explaining usage +- **Changed behavior**: Update descriptions and examples +- **Deprecated features**: Add deprecation notices and migration guidance +- **New examples**: Add code blocks following conventions + +### Step 3: Apply updates with confirmation + +For each change: + +1. Show the user what you plan to change +2. Wait for confirmation before editing +3. Apply the edit +4. Move to the next change + +### Step 4: Check for shared content + +If the doc uses the `source` field pattern (common for Pages Router docs), the source file is the one to edit. Example: + +```yaml +# docs/02-pages/... file with shared content +--- +source: app/building-your-application/optimizing/images +--- +``` + +Edit the App Router source, not the Pages Router file. + +### Step 5: Validate changes + +```bash +pnpm lint # Check formatting +pnpm prettier-fix # Auto-fix formatting issues +``` + +## Workflow: Scaffold New Feature Documentation + +Use this when adding documentation for entirely new features. + +### Step 1: Determine the doc type + +| Feature Type | Doc Location | Template | +| ------------------- | --------------------------------------------------- | ---------------- | +| New component | `docs/01-app/03-api-reference/02-components/` | API Reference | +| New function | `docs/01-app/03-api-reference/04-functions/` | API Reference | +| New config option | `docs/01-app/03-api-reference/05-config/` | Config Reference | +| New concept/guide | `docs/01-app/02-guides/` | Guide | +| New file convention | `docs/01-app/03-api-reference/03-file-conventions/` | File Convention | + +### Step 2: Create the file with proper naming + +- Use kebab-case: `my-new-feature.mdx` +- Add numeric prefix if ordering matters: `05-my-new-feature.mdx` +- Place in the correct directory based on feature type + +### Step 3: Use the appropriate template + +**API Reference Template:** + +```mdx +--- +title: Feature Name +description: Brief description of what this feature does. +--- + +{/* The content of this doc is shared between the app and pages router. You can use the `Content` component to add content that is specific to the Pages Router. Any shared content should not be wrapped in a component. */} + +Brief introduction to the feature. + +## Reference + +### Props + +
+ +| Prop | Example | Type | Status | +| ----------------------- | ------------------ | ------ | -------- | +| [`propName`](#propname) | `propName="value"` | String | Required | + +
+ +#### `propName` + +Description of the prop. + +\`\`\`tsx filename="app/example.tsx" switcher +// TypeScript example +\`\`\` + +\`\`\`jsx filename="app/example.js" switcher +// JavaScript example +\`\`\` +``` + +**Guide Template:** + +```mdx +--- +title: How to do X in Next.js +nav_title: X +description: Learn how to implement X in your Next.js application. +--- + +Introduction explaining why this guide is useful. + +## Prerequisites + +What the reader needs to know before starting. + +## Step 1: First Step + +Explanation and code example. + +\`\`\`tsx filename="app/example.tsx" switcher +// Code example +\`\`\` + +## Step 2: Second Step + +Continue with more steps... + +## Next Steps + +Related topics to explore. +``` + +### Step 4: Add related links + +Update frontmatter with related documentation: + +```yaml +related: + title: Next Steps + description: Learn more about related features. + links: + - app/api-reference/functions/related-function + - app/guides/related-guide +``` + +## Documentation Conventions + +See `references/DOC-CONVENTIONS.md` for complete formatting rules. + +### Quick Reference + +**Frontmatter (required):** + +```yaml +--- +title: Page Title (2-3 words) +description: One or two sentences describing the page. +--- +``` + +**Code blocks:** + +``` +\`\`\`tsx filename="app/page.tsx" switcher +// TypeScript first +\`\`\` + +\`\`\`jsx filename="app/page.js" switcher +// JavaScript second +\`\`\` +``` + +**Router-specific content:** + +```mdx +Content only for App Router docs. + +Content only for Pages Router docs. +``` + +**Notes:** + +```mdx +> **Good to know**: Single line note. + +> **Good to know**: +> +> - Multi-line note point 1 +> - Multi-line note point 2 +``` + +## Validation Checklist + +Before committing documentation changes: + +- [ ] Frontmatter has `title` and `description` +- [ ] Code blocks have `filename` attribute +- [ ] TypeScript examples use `switcher` with JS variant +- [ ] Props tables are properly formatted +- [ ] Related links point to valid paths +- [ ] `pnpm lint` passes +- [ ] Changes render correctly (if preview available) + +## References + +- `references/DOC-CONVENTIONS.md` - Complete frontmatter and formatting rules +- `references/CODE-TO-DOCS-MAPPING.md` - Source code to documentation mapping diff --git a/.claude/skills/update-docs/references/CODE-TO-DOCS-MAPPING.md b/.claude/skills/update-docs/references/CODE-TO-DOCS-MAPPING.md new file mode 100644 index 0000000000000..46405a1d77b74 --- /dev/null +++ b/.claude/skills/update-docs/references/CODE-TO-DOCS-MAPPING.md @@ -0,0 +1,136 @@ +# Code to Documentation Mapping + +Maps Next.js source code directories to their corresponding documentation files. + +## Core Mappings + +### Components + +| Source Path | Documentation Path | +| ------------------------------------------------ | ------------------------------------------------------- | +| `packages/next/src/client/components/image.tsx` | `docs/01-app/03-api-reference/02-components/image.mdx` | +| `packages/next/src/client/components/link.tsx` | `docs/01-app/03-api-reference/02-components/link.mdx` | +| `packages/next/src/client/components/script.tsx` | `docs/01-app/03-api-reference/02-components/script.mdx` | +| `packages/next/src/client/components/form.tsx` | `docs/01-app/03-api-reference/02-components/form.mdx` | + +### Functions + +| Source Path | Documentation Path | +| ---------------------------------------------------- | ----------------------------------------------------------------- | +| `packages/next/src/server/request/` | `docs/01-app/03-api-reference/04-functions/` | +| `packages/next/src/server/lib/metadata/` | `docs/01-app/03-api-reference/04-functions/generate-metadata.mdx` | +| `packages/next/src/client/components/navigation.tsx` | `docs/01-app/03-api-reference/04-functions/use-router.mdx` | +| `packages/next/src/client/components/navigation.tsx` | `docs/01-app/03-api-reference/04-functions/use-pathname.mdx` | +| `packages/next/src/client/components/navigation.tsx` | `docs/01-app/03-api-reference/04-functions/use-search-params.mdx` | + +### File Conventions + +| Source Path | Documentation Path | +| ------------------------------------------ | ------------------------------------------------------------- | +| `packages/next/src/build/webpack/loaders/` | `docs/01-app/03-api-reference/03-file-conventions/` | +| `packages/next/src/server/app-render/` | `docs/01-app/03-api-reference/03-file-conventions/layout.mdx` | +| `packages/next/src/server/app-render/` | `docs/01-app/03-api-reference/03-file-conventions/page.mdx` | + +### Configuration + +| Source Path | Documentation Path | +| ------------------------------------------- | ----------------------------------------------------------- | +| `packages/next/src/server/config-shared.ts` | `docs/01-app/03-api-reference/05-config/01-next-config-js/` | +| `packages/next/src/server/config.ts` | `docs/01-app/03-api-reference/05-config/01-next-config-js/` | +| `packages/next/src/build/webpack-config.ts` | `docs/01-app/03-api-reference/05-config/01-next-config-js/` | + +### Directives + +| Source Path | Documentation Path | +| ---------------------------------------- | ----------------------------------------------------------- | +| `packages/next/src/server/use-cache/` | `docs/01-app/03-api-reference/01-directives/use-cache.mdx` | +| `packages/next/src/client/use-client.ts` | `docs/01-app/03-api-reference/01-directives/use-client.mdx` | +| `packages/next/src/server/use-server.ts` | `docs/01-app/03-api-reference/01-directives/use-server.mdx` | + +### Metadata File Conventions + +| Source Path | Documentation Path | +| --------------------------------- | ---------------------------------------------------------------------------------- | +| `packages/next/src/lib/metadata/` | `docs/01-app/03-api-reference/03-file-conventions/01-metadata/` | +| Metadata icons handling | `docs/01-app/03-api-reference/03-file-conventions/01-metadata/app-icons.mdx` | +| Open Graph images | `docs/01-app/03-api-reference/03-file-conventions/01-metadata/opengraph-image.mdx` | +| Sitemap generation | `docs/01-app/03-api-reference/03-file-conventions/01-metadata/sitemap.mdx` | + +## Directory Pattern Mappings + +### By Feature Area + +| Source Directory | Documentation Area | Notes | +| -------------------------------------- | --------------------------------------------- | ---------------------- | +| `packages/next/src/client/` | `docs/01-app/03-api-reference/02-components/` | Client-side components | +| `packages/next/src/server/` | `docs/01-app/03-api-reference/04-functions/` | Server functions | +| `packages/next/src/build/` | `docs/01-app/03-api-reference/05-config/` | Build configuration | +| `packages/next/src/shared/lib/router/` | `docs/01-app/02-guides/` | Routing guides | +| `packages/next/src/lib/metadata/` | `docs/01-app/02-guides/metadata/` | Metadata guides | + +### CLI Commands + +| Source Path | Documentation Path | +| ------------------------------------- | ---------------------------------------------------- | +| `packages/next/src/cli/next-dev.ts` | `docs/01-app/03-api-reference/06-cli/next-dev.mdx` | +| `packages/next/src/cli/next-build.ts` | `docs/01-app/03-api-reference/06-cli/next-build.mdx` | +| `packages/next/src/cli/next-start.ts` | `docs/01-app/03-api-reference/06-cli/next-start.mdx` | + +## Finding Related Documentation + +### Step 1: Identify the changed export + +Look at what's exported from the changed file: + +- Public API exports → API Reference docs +- Internal utilities → Usually no docs needed +- Configuration types → Config docs + +### Step 2: Search for existing docs + +Use Claude's built-in tools for searching: + +- **Find docs mentioning a term**: Use the Grep tool with the pattern and `docs/` as the path +- **List docs in a directory**: Use the Glob tool with pattern like `docs/01-app/03-api-reference/04-functions/*.mdx` + +### Step 3: Check for shared content + +If editing App Router docs, check if Pages Router has a corresponding file with `source` field: + +- **Find source references**: Use the Grep tool with pattern `source: app/api-reference` in `docs/02-pages/` + +## Common Patterns + +### New API Function + +1. Export added to `packages/next/src/server/` +2. Create doc at `docs/01-app/03-api-reference/04-functions/function-name.mdx` +3. Update index/listing pages if applicable + +### New Component Prop + +1. Prop added to component in `packages/next/src/client/components/` +2. Update the props table in corresponding doc +3. Add a section explaining the new prop with examples + +### New Config Option + +1. Option added to `packages/next/src/server/config-shared.ts` +2. Find the relevant config doc in `docs/01-app/03-api-reference/05-config/01-next-config-js/` +3. Add the option with description and example + +### Behavioral Change + +1. Logic changed in any source file +2. Find all docs that describe this behavior +3. Update descriptions and examples to match new behavior +4. Add migration notes if breaking change + +## Quick Search Commands + +Use Claude's built-in tools for efficient searching: + +- **Find all docs mentioning a term**: Use the Grep tool with your search pattern and `docs/` as the path, filtering to `*.mdx` files +- **List all API reference docs**: Use the Glob tool with pattern `docs/01-app/03-api-reference/**/*.mdx` +- **Find docs by filename pattern**: Use the Glob tool with pattern like `docs/**/*image*.mdx` +- **Read a doc's frontmatter**: Use the Read tool with a line limit to check the `source` field diff --git a/.claude/skills/update-docs/references/DOC-CONVENTIONS.md b/.claude/skills/update-docs/references/DOC-CONVENTIONS.md new file mode 100644 index 0000000000000..8c0f4af81dbec --- /dev/null +++ b/.claude/skills/update-docs/references/DOC-CONVENTIONS.md @@ -0,0 +1,236 @@ +# Next.js Documentation Conventions + +Complete reference for frontmatter schema, code block formatting, and MDX component usage. + +## Frontmatter Schema + +All MDX files must start with YAML frontmatter enclosed in `---` delimiters. + +### Required Fields + +| Field | Description | Example | +| ------------- | ------------------------------------------- | ------------------------------------------------ | +| `title` | Page title for SEO and headings (2-3 words) | `title: Image Component` | +| `description` | Brief description (1-2 sentences) | `description: Optimize images using next/image.` | + +### Optional Fields + +| Field | Description | Example | +| ----------- | -------------------------------------------------- | -------------------------------------------- | +| `nav_title` | Shorter title for navigation sidebar | `nav_title: Image` | +| `source` | Pull content from another page (avoid duplication) | `source: app/api-reference/components/image` | +| `related` | Next steps section with related links | See below | +| `version` | Development stage indicator | `version: experimental` | + +### Related Links Format + +```yaml +--- +title: My Feature +description: Description here. +related: + title: Next Steps + description: Learn more about related features. + links: + - app/api-reference/components/image + - app/guides/optimizing/images +--- +``` + +### Version Field Values + +- `experimental` - Experimental feature, may change +- `legacy` - Legacy feature, consider alternatives +- `unstable` - Unstable API, not recommended for production +- `RC` - Release candidate + +## Code Block Conventions + +### Basic Syntax + +```` +```language filename="path/to/file.ext" +code here +``` +```` + +### Required Attributes + +| Attribute | When to Use | Example | +| ----------- | --------------------------------- | ------------------------- | +| `filename` | Always for code examples | `filename="app/page.tsx"` | +| `switcher` | When providing TS and JS variants | `switcher` | +| `highlight` | To highlight specific lines | `highlight={1,3-5}` | + +### TypeScript/JavaScript Switcher Pattern + +Always provide TypeScript first, then JavaScript: + +````mdx +```tsx filename="app/page.tsx" switcher +import type { Metadata } from 'next' + +export const metadata: Metadata = { + title: 'My Page', +} +``` + +```jsx filename="app/page.js" switcher +export const metadata = { + title: 'My Page', +} +``` +```` + +### Terminal Commands + +Use `bash` language without filename: + +````mdx +```bash +npm install next +``` +```` + +### Highlighting Lines + +``` +highlight={1} # Single line +highlight={1,3} # Multiple lines +highlight={1-5} # Range +highlight={1,3-5,8} # Combined +``` + +## MDX Components + +### AppOnly / PagesOnly + +Use for router-specific content in shared documentation: + +```mdx + + +This content only appears in App Router documentation. + + + + + +This content only appears in Pages Router documentation. + + +``` + +**Important:** Include blank lines inside the components for proper markdown parsing. + +### Image Component + +For themed images with light/dark variants: + +```mdx +Description of the image +``` + +### Notes and Callouts + +**Single line:** + +```mdx +> **Good to know**: Important information here. +``` + +**Multi-line:** + +```mdx +> **Good to know**: +> +> - First point +> - Second point +> - Third point +``` + +## Props Tables + +Use HTML table wrapper for horizontal scroll on mobile: + +```mdx +
+ +| Prop | Example | Type | Status | +| ----------------- | ------------------- | ------- | -------- | +| [`src`](#src) | `src="/image.png"` | String | Required | +| [`alt`](#alt) | `alt="Description"` | String | Required | +| [`width`](#width) | `width={500}` | Integer | - | + +
+``` + +### Status Values + +- `Required` - Must be provided +- `-` - Optional +- `Deprecated` - Will be removed, use alternative + +## Shared Content Pattern + +For Pages Router docs that share content with App Router: + +**App Router (source):** `docs/01-app/03-api-reference/02-components/image.mdx` + +- Contains the full documentation +- Uses `` and `` for router-specific sections + +**Pages Router (consumer):** `docs/02-pages/03-api-reference/01-components/image.mdx` + +```yaml +--- +title: Image Component +description: Optimize images using next/image. +source: app/api-reference/components/image +--- +``` + +The `source` field pulls content from the App Router doc. + +## Writing Style + +### Voice + +- **Guides:** Instructional, use "you" to address users +- **API Reference:** Technical, use imperative verbs ("create", "pass", "return") + +### Clarity + +- Use plain words over complex alternatives +- Be specific: "the `src` prop" not "this prop" +- Avoid jargon unless explaining it + +### Structure + +Typical page structure: + +1. Brief introduction (what and why) +2. Minimal working example +3. Detailed reference/options +4. Examples for different use cases +5. Related links (via frontmatter) + +## File Naming + +- Use kebab-case: `generate-metadata.mdx` +- Add numeric prefix for ordering: `01-installation.mdx` +- Index pages: `index.mdx` + +## Validation Commands + +```bash +pnpm lint # Full lint check +pnpm prettier-fix # Fix formatting +pnpm types # TypeScript check +``` diff --git a/crates/napi/src/next_api/turbopack_ctx.rs b/crates/napi/src/next_api/turbopack_ctx.rs index 3b018273c77a6..dbdeb0f134070 100644 --- a/crates/napi/src/next_api/turbopack_ctx.rs +++ b/crates/napi/src/next_api/turbopack_ctx.rs @@ -158,7 +158,7 @@ pub struct NapiNextTurbopackCallbacks { throw_turbopack_internal_error: ThreadsafeFunction, } -/// Arguments for [`NapiNextTurbopackCallbacks::throw_turbopack_internal_error`]. +/// Arguments for `NapiNextTurbopackCallbacks::throw_turbopack_internal_error`. #[napi(object)] pub struct TurbopackInternalErrorOpts { pub message: String, diff --git a/docs/01-app/03-api-reference/05-config/01-next-config-js/browserDebugInfoInTerminal.mdx b/docs/01-app/03-api-reference/05-config/01-next-config-js/browserDebugInfoInTerminal.mdx index 4a0e853f601fb..db6aca4aa11e4 100644 --- a/docs/01-app/03-api-reference/05-config/01-next-config-js/browserDebugInfoInTerminal.mdx +++ b/docs/01-app/03-api-reference/05-config/01-next-config-js/browserDebugInfoInTerminal.mdx @@ -1,134 +1,34 @@ --- title: browserDebugInfoInTerminal description: Forward browser console logs and errors to your terminal during development. -version: experimental +redirect: /docs/app/api-reference/config/next-config-js/logging#browser-console-logs --- -The `experimental.browserDebugInfoInTerminal` option forwards console output and runtime errors originating in the browser to the dev server terminal. +This configuration option has been moved to [`logging.browserToTerminal`](/docs/app/api-reference/config/next-config-js/logging#browser-console-logs). -This option is disabled by default. When enabled it only works in development mode. +## Migration -## Usage +To migrate to the new configuration, replace `experimental.browserDebugInfoInTerminal` with `logging.browserToTerminal`: -Enable forwarding: - -```ts filename="next.config.ts" switcher -import type { NextConfig } from 'next' - -const nextConfig: NextConfig = { - experimental: { - browserDebugInfoInTerminal: true, - }, -} - -export default nextConfig -``` - -```js filename="next.config.js" switcher -/** @type {import('next').NextConfig} */ -const nextConfig = { +```js filename="next.config.js" +// Before +module.exports = { experimental: { browserDebugInfoInTerminal: true, }, } -module.exports = nextConfig -``` - -### Serialization limits - -Deeply nested objects/arrays are truncated using **sensible defaults**. You can tweak these limits: - -- **depthLimit**: (optional) Limit stringification depth for nested objects/arrays. Default: 5 -- **edgeLimit**: (optional) Max number of properties or elements to include per object or array. Default: 100 - -```ts filename="next.config.ts" switcher -import type { NextConfig } from 'next' - -const nextConfig: NextConfig = { - experimental: { - browserDebugInfoInTerminal: { - depthLimit: 5, - edgeLimit: 100, - }, - }, -} - -export default nextConfig -``` - -```js filename="next.config.js" switcher -/** @type {import('next').NextConfig} */ -const nextConfig = { - experimental: { - browserDebugInfoInTerminal: { - depthLimit: 5, - edgeLimit: 100, - }, - }, -} - -module.exports = nextConfig -``` - -### Source location - -Source locations are included by default when this feature is enabled. - -```tsx filename="app/page.tsx" highlight={8} -'use client' - -export default function Home() { - return ( - - ) -} -``` - -Clicking the button prints this message to the terminal. - -```bash filename="Terminal" -[browser] Hello World (app/page.tsx:8:17) -``` - -To suppress them, set `showSourceLocation: false`. - -- **showSourceLocation**: Include source location info when available. - -```ts filename="next.config.ts" switcher -import type { NextConfig } from 'next' - -const nextConfig: NextConfig = { - experimental: { - browserDebugInfoInTerminal: { - showSourceLocation: false, - }, +// After +module.exports = { + logging: { + browserToTerminal: true, }, } - -export default nextConfig ``` -```js filename="next.config.js" switcher -/** @type {import('next').NextConfig} */ -const nextConfig = { - experimental: { - browserDebugInfoInTerminal: { - showSourceLocation: false, - }, - }, -} - -module.exports = nextConfig -``` +The new `logging.browserToTerminal` option supports the log level values (`true`, `'warn'`, `'error'`). Note that the object configuration options (`depthLimit`, `edgeLimit`, `showSourceLocation`) are no longer available in the new configuration. | Version | Changes | | --------- | ---------------------------------------------------- | | `v15.4.0` | experimental `browserDebugInfoInTerminal` introduced | +| `v16.2.x` | Moved to stable as `logging.browserToTerminal` | diff --git a/docs/01-app/03-api-reference/05-config/01-next-config-js/logging.mdx b/docs/01-app/03-api-reference/05-config/01-next-config-js/logging.mdx index a5551a5575547..f00e08bfb0aec 100644 --- a/docs/01-app/03-api-reference/05-config/01-next-config-js/logging.mdx +++ b/docs/01-app/03-api-reference/05-config/01-next-config-js/logging.mdx @@ -1,6 +1,6 @@ --- title: logging -description: Configure how data fetches are logged to the console when running Next.js in development mode. +description: Configure logging behavior in the terminal when running Next.js in development mode. --- {/* The content of this doc is shared between the app and pages router. You can use the `Content` component to add content that is specific to the Pages Router. Any shared content should not be wrapped in a component. */} @@ -11,8 +11,6 @@ description: Configure how data fetches are logged to the console when running N You can configure the logging level and whether the full URL is logged to the console when running Next.js in development mode. -Currently, `logging` only applies to data fetching using the `fetch` API. It does not yet apply to other logs inside of Next.js. - ```js filename="next.config.js" module.exports = { logging: { @@ -60,6 +58,64 @@ module.exports = { } ``` +### Browser Console Logs + +You can forward browser console logs (such as `console.log`, `console.warn`, `console.error`) to the terminal during development. This is useful for debugging client-side code without needing to check the browser's developer tools. + +```js filename="next.config.js" +module.exports = { + logging: { + browserToTerminal: true, + }, +} +``` + +#### Options + +The `browserToTerminal` option accepts the following values: + +| Value | Description | +| --------- | --------------------------------------------------- | +| `'warn'` | Forward only warnings and errors, by default | +| `'error'` | Forward only errors | +| `true` | Forward all console output (log, info, warn, error) | +| `false` | Disable browser log forwarding | + +```js filename="next.config.js" +module.exports = { + logging: { + browserToTerminal: 'warn', + }, +} +``` + +#### Source Location + +When enabled, browser logs include source location information (file path and line number) by default. For example: + +```tsx filename="app/page.tsx" highlight={8} +'use client' + +export default function Home() { + return ( + + ) +} +``` + +Clicking the button prints this message to the terminal: + +```bash filename="Terminal" +[browser] Hello World (app/page.tsx:8:17) +``` + ### Disabling Logging In addition, you can disable the development logging by setting `logging` to `false`. diff --git a/packages/next/src/build/define-env.ts b/packages/next/src/build/define-env.ts index 40e3f656feeb0..a2cafd4d8260b 100644 --- a/packages/next/src/build/define-env.ts +++ b/packages/next/src/build/define-env.ts @@ -332,7 +332,7 @@ export function getDefineEnv({ : {}), 'process.env.__NEXT_BROWSER_DEBUG_INFO_IN_TERMINAL': JSON.stringify( - config.experimental.browserDebugInfoInTerminal || false + (config.logging && config.logging.browserToTerminal) || false ), 'process.env.__NEXT_MCP_SERVER': !!config.experimental.mcpServer, diff --git a/packages/next/src/next-devtools/dev-overlay/components/call-stack-frame/call-stack-frame.tsx b/packages/next/src/next-devtools/dev-overlay/components/call-stack-frame/call-stack-frame.tsx index 32f51a3763cd7..855db485e0941 100644 --- a/packages/next/src/next-devtools/dev-overlay/components/call-stack-frame/call-stack-frame.tsx +++ b/packages/next/src/next-devtools/dev-overlay/components/call-stack-frame/call-stack-frame.tsx @@ -2,7 +2,7 @@ import type { OriginalStackFrame } from '../../../shared/stack-frame' import { HotlinkedText } from '../hot-linked-text' import { ExternalIcon, SourceMappingErrorIcon } from '../../icons/external' -import { getFrameSource } from '../../../shared/stack-frame' +import { getStackFrameFile } from '../../../shared/stack-frame' import { useOpenInEditor } from '../../utils/use-open-in-editor' export const CallStackFrame: React.FC<{ @@ -11,9 +11,9 @@ export const CallStackFrame: React.FC<{ // TODO: ability to expand resolved frames const f = frame.originalStackFrame ?? frame.sourceStackFrame - const hasSource = Boolean(frame.originalCodeFrame) + const hasOriginalCodeFrame = Boolean(frame.originalCodeFrame) const open = useOpenInEditor( - hasSource + hasOriginalCodeFrame ? { file: f.file, line1: f.line1 ?? 1, @@ -24,21 +24,21 @@ export const CallStackFrame: React.FC<{ // Formatted file source could be empty. e.g. will be formatted to empty string, // we'll skip rendering the frame in this case. - const fileSource = getFrameSource(f) + const stackFrameFile = getStackFrameFile(f) - if (!fileSource) { + if (!stackFrameFile) { return null } return (
- {hasSource && ( + {hasOriginalCodeFrame && (
) @@ -140,9 +140,10 @@ export const CALL_STACK_FRAME_STYLES = ` } } - .call-stack-frame-file-source { + .call-stack-frame-file { color: var(--color-gray-900); font-size: var(--size-14); line-height: var(--size-20); + word-wrap: break-word; } ` diff --git a/packages/next/src/next-devtools/dev-overlay/components/code-frame/code-frame.tsx b/packages/next/src/next-devtools/dev-overlay/components/code-frame/code-frame.tsx index e23535ab10b48..be8bab972b158 100644 --- a/packages/next/src/next-devtools/dev-overlay/components/code-frame/code-frame.tsx +++ b/packages/next/src/next-devtools/dev-overlay/components/code-frame/code-frame.tsx @@ -1,6 +1,6 @@ import { useMemo } from 'react' import { HotlinkedText } from '../hot-linked-text' -import { getFrameSource, type StackFrame } from '../../../shared/stack-frame' +import { getStackFrameFile, type StackFrame } from '../../../shared/stack-frame' import { useOpenInEditor } from '../../utils/use-open-in-editor' import { ExternalIcon } from '../../icons/external' import { FileIcon } from '../../icons/file' @@ -49,7 +49,7 @@ export function CodeFrame({ stackFrame, codeFrame }: CodeFrameProps) { - {getFrameSource(stackFrame)} @{' '} + {getStackFrameFile(stackFrame)} @{' '}