gavmac00/nextjs-app-docs huggingface dataset:
Sass
Next.js has built-in support for Sass using both the .scss and .sass extensions. You can use component-level Sass via CSS Modules and the .module.scssor .module.sass extension.
First, install sass:
Terminal npm install --save-dev sass
Good to know:
Sass supports two different syntax, each with their own extension.
The .scss extension requires you use the SCSS syntax,
while the .sass extension requires you use the Indented Syntax ("Sass").
If you're not sure which to choose, start with the .scss extension which is a superset of CSS, and doesn't require you learn the
Indented Syntax ("Sass").
Customizing Sass Options
If you want to configure the Sass compiler, use sassOptions in next.config.js.
next.config.js const path = require('path')
 
module.exports = {
  sassOptions: {
module.exports = {
  sassOptions: {
    includePaths: [path.join(__dirname, 'styles')],
  },
}
Sass Variables
Next.js supports Sass variables exported from CSS Module files.
For example, using the exported primaryColor Sass variable:
app/variables.module.scss $primary-color: #64ff00;
 
:export {
  primaryColor: $primary-color;
}
app/page.js // maps to root `/` URL
 
import variables from './variables.module.scss'
 
export default function Page() {
  return <h1 style={{ color: variables.primaryColor }}>Hello, Next.js!</h1>
}
CSS-in-JS
Warning: CSS-in-JS libraries which require runtime JavaScript are not currently supported in Server Components. Using CSS-in-JS with newer React features like Server Components and Streaming requires library authors to support the latest version of React, including concurrent rendering.
We're working with the React team on upstream APIs to handle CSS and JavaScript assets with support for React Server Components and streaming architecture.
The following libraries are supported in Client Components in the app directory (alphabetical):
kuma-ui
@mui/material
pandacss
styled-jsx
styled-components
style9
tamagui
tss-react
vanilla-extract
The following are currently working on support:
emotion
Good to know: We're testing out different CSS-in-JS libraries and we'll be adding more examples for libraries that support React 18 features and/or the app directory.
If you want to style Server Components, we recommend using CSS Modules or other solutions that output CSS files, like PostCSS or Tailwind CSS.Configuring CSS-in-JS in app
Configuring CSS-in-JS is a three-step opt-in process that involves:
A style registry to collect all CSS rules in a render.
The new useServerInsertedHTML hook to inject rules before any content that might use them.
A Client Component that wraps your app with the style registry during initial server-side rendering.
styled-jsx
Using styled-jsx in Client Components requires using v5.1.0. First, create a new registry:app/registry.tsx 'use client'
 
import React, { useState } from 'react'
import { useServerInsertedHTML } from 'next/navigation'
import { StyleRegistry, createStyleRegistry } from 'styled-jsx'
 
export default function StyledJsxRegistry({
  children,
export default function StyledJsxRegistry({
  children,
}: {
  children: React.ReactNode
}) {
  // Only create stylesheet once with lazy initial state
  // x-ref: https://reactjs.org/docs/hooks-reference.html#lazy-initial-state
  const [jsxStyleRegistry] = useState(() => createStyleRegistry())
 
  useServerInsertedHTML(() => {
    const styles = jsxStyleRegistry.styles()
    jsxStyleRegistry.flush()
    return <>{styles}</>
  })
 
  return <StyleRegistry registry={jsxStyleRegistry}>{children}</StyleRegistry>
}Then, wrap your root layout with the registry:app/layout.tsx import StyledJsxRegistry from './registry'
 
export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <html>
      <body>
}) {
  return (
    <html>
      <body>
        <StyledJsxRegistry>{children}</StyledJsxRegistry>
      </body>
    </html>
  )
}View an example here.Styled Components
Below is an example of how to configure styled-components@v6.0.0-rc.1 or greater:First, use the styled-components API to create a global registry component to collect all CSS style rules generated during a render, and a function to return those rules. Then use the useServerInsertedHTML hook to inject the styles collected in the registry into the <head> HTML tag in the root layout.lib/registry.tsx 'use client'
 
import React, { useState } from 'react'
import { useServerInsertedHTML } from 'next/navigation'
import { ServerStyleSheet, StyleSheetManager } from 'styled-components'
 
export default function StyledComponentsRegistry({
export default function StyledComponentsRegistry({
  children,
}: {
  children: React.ReactNode
}) {
  // Only create stylesheet once with lazy initial state
  // x-ref: https://reactjs.org/docs/hooks-reference.html#lazy-initial-state
  const [styledComponentsStyleSheet] = useState(() => new ServerStyleSheet())
 
  useServerInsertedHTML(() => {
    const styles = styledComponentsStyleSheet.getStyleElement()
    styledComponentsStyleSheet.instance.clearTag()
    return <>{styles}</>
  })
 
  if (typeof window !== 'undefined') return <>{children}</>
 
  return (
    <StyleSheetManager sheet={styledComponentsStyleSheet.instance}>
      {children}
    </StyleSheetManager>
  )
}Wrap the children of the root layout with the style registry component:app/layout.tsx import StyledComponentsRegistry from './lib/registry'
export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <html>
      <body>
        <StyledComponentsRegistry>{children}</StyledComponentsRegistry>
      </body>
    </html>
  )
}View an example here.
Good to know:
During server rendering, styles will be extracted to a global registry and flushed to the <head> of your HTML. This ensures the style rules are placed before any content that might use them. In the future, we may use an upcoming React feature to determine where to inject the styles.
During streaming, styles from each chunk will be collected and appended to existing styles. After client-side hydration is complete, styled-components will take over as usual and inject any further dynamic styles.
We specifically use a Client Component at the top level of the tree for the style registry because it's more efficient to extract CSS rules this way. It avoids re-generating styles on subsequent server renders, and prevents them from being sent in the Server Component payload.
CodemodsCodemods are transformations that run on your codebase programmatically. This allows a large number of changes to be programmatically applied without having to manually go through every file.
Next.js provides Codemod transformations to help upgrade your Next.js codebase when an API is updated or deprecated.
Usage
In your terminal, navigate (cd) into your project's folder, then run:
Terminal npx @next/codemod <transform> <path>
Replacing <transform> and <path> with appropriate values.
transform - name of transform
path - files or directory to transform
--dry Do a dry-run, no code will be edited
--print Prints the changed output for comparison
Next.js Codemods
13.2
Use Built-in Font
built-in-next-font
Terminal npx @next/codemod@latest built-in-next-font .
Terminal npx @next/codemod@latest built-in-next-font .
This codemod uninstalls the @next/font package and transforms @next/font imports into the built-in next/font.
For example:
 import { Inter } from '@next/font/google'
Transforms into:
 import { Inter } from 'next/font/google'
13.0
Rename Next Image Imports
next-image-to-legacy-image
Terminal npx @next/codemod@latest next-image-to-legacy-image .
Safely renames next/image imports in existing Next.js 10, 11, or 12 applications to next/legacy/image in Next.js 13. Also renames next/future/image to next/image.
For example:
pages/index.js import Image1 from 'next/image'
import Image2 from 'next/future/image'
 
export default function Home() {
  return (
    <div>
export default function Home() {
  return (
    <div>
      <Image1 src="/test.jpg" width="200" height="300" />
      <Image2 src="/test.png" width="500" height="400" />
    </div>
  )
}
Transforms into:
pages/index.js // 'next/image' becomes 'next/legacy/image'
import Image1 from 'next/legacy/image'
// 'next/future/image' becomes 'next/image'
import Image2 from 'next/image'
 
export default function Home() {
  return (
    <div>
      <Image1 src="/test.jpg" width="200" height="300" />
      <Image2 src="/test.png" width="500" height="400" />
    </div>
  )
}
Migrate to the New Image Component
next-image-experimental
)
}
Migrate to the New Image Component
next-image-experimental
Terminal npx @next/codemod@latest next-image-experimental .
Dangerously migrates from next/legacy/image to the new next/image by adding inline styles and removing unused props.
Removes layout prop and adds style.
Removes objectFit prop and adds style.
Removes objectPosition prop and adds style.
Removes lazyBoundary prop.
Removes lazyRoot prop.
Remove <a> Tags From Link Components
new-link
Terminal npx @next/codemod@latest new-link .
Remove <a> tags inside Link Components, or add a legacyBehavior prop to Links that cannot be auto-fixed.
For example:
 <Link href="/about">
  <a>About</a>
</Link>
// transforms into
<Link href="/about">
  About
</Link>
 
<Link href="/about">
About
</Link>
 
<Link href="/about">
  <a onClick={() => console.log('clicked')}>About</a>
</Link>
// transforms into
<Link href="/about" onClick={() => console.log('clicked')}>
  About
</Link>
In cases where auto-fixing can't be applied, the legacyBehavior prop is added. This allows your app to keep functioning using the old behavior for that particular link.
 const Component = () => <a>About</a>
 
<Link href="/about">
  <Component />
</Link>
// becomes
<Link href="/about" legacyBehavior>
  <Component />
</Link>
11
Migrate from CRA
cra-to-next
Terminal npx @next/codemod cra-to-next
cra-to-next
Terminal npx @next/codemod cra-to-next
Migrates a Create React App project to Next.js; creating a Pages Router and necessary config to match behavior. Client-side only rendering is leveraged initially to prevent breaking compatibility due to window usage during SSR and can be enabled seamlessly to allow the gradual adoption of Next.js specific features.
Please share any feedback related to this transform in this discussion.
10
Add React imports
add-missing-react-import
Terminal npx @next/codemod add-missing-react-import
Transforms files that do not import React to include the import in order for the new React JSX transform to work.
For example:
my-component.js export default class Home extends React.Component {
  render() {
    return <div>Hello World</div>
  }
}
Transforms into:
my-component.js import React from 'react'
export default class Home extends React.Component {
my-component.js import React from 'react'
export default class Home extends React.Component {
  render() {
    return <div>Hello World</div>
  }
}
9
Transform Anonymous Components into Named Components
name-default-component
Terminal npx @next/codemod name-default-component
Versions 9 and above.
Transforms anonymous components into named components to make sure they work with Fast Refresh.
For example:
my-component.js export default function () {
  return <div>Hello World</div>
}
Transforms into:
my-component.js export default function MyComponent() {
  return <div>Hello World</div>
}
The component will have a camel-cased name based on the name of the file, and it also works with arrow functions.
8
Transform AMP HOC into page config
withamp-to-config
Terminal npx @next/codemod withamp-to-config
withamp-to-config
Terminal npx @next/codemod withamp-to-config
Transforms the withAmp HOC into Next.js 9 page configuration.
For example:
 // Before
import { withAmp } from 'next/amp'
 
function Home() {
  return <h1>My AMP Page</h1>
}
 
export default withAmp(Home)
 // After
export default function Home() {
  return <h1>My AMP Page</h1>
}
 
export const config = {
  amp: true,
}
6
Use withRouter
url-to-withrouter
Terminal npx @next/codemod url-to-withrouter
Transforms the deprecated automatically injected url property on top level pages to using withRouter and the router property it injects. Read more here: https://nextjs.org/docs/messages/url-deprecated
For example:
For example:
From import React from 'react'
export default class extends React.Component {
  render() {
    const { pathname } = this.props.url
    return <div>Current pathname: {pathname}</div>
  }
}
To import React from 'react'
import { withRouter } from 'next/router'
export default withRouter(
  class extends React.Component {
    render() {
      const { pathname } = this.props.router
      return <div>Current pathname: {pathname}</div>
    }
  }
)
This is one case. All the cases that are transformed (and tested) can be found in the __testfixtures__ directory.
App Router Incremental Adoption GuideThis guide will help you:
Update your Next.js application from version 12 to version 13
Upgrade features that work in both the pages and the app directories
Incrementally migrate your existing application from pages to app
Upgrading
Node.js Version
The minimum Node.js version is now v16.8. See the Node.js documentation for more information.
Next.js Version
To update to Next.js version 13, run the following command using your preferred package manager:
Terminal npm install next@latest react@latest react-dom@latest
ESLint Version
If you're using ESLint, you need to upgrade your ESLint version:
Terminal npm install -D eslint-config-next@latest
Terminal npm install -D eslint-config-next@latest
Good to know: You may need to restart the ESLint server in VS Code for the ESLint changes to take effect. Open the Command Palette (cmd+shift+p on Mac; ctrl+shift+p on Windows) and search for ESLint: Restart ESLint Server.
Next Steps
After you've updated, see the following sections for next steps:
Upgrade new features: A guide to help you upgrade to new features such as the improved Image and Link Components.
Migrate from the pages to app directory: A step-by-step guide to help you incrementally migrate from the pages to the app directory.
Upgrading New Features
Next.js 13 introduced the new App Router with new features and conventions. The new Router is available in the app directory and co-exists with the pages directory.
Upgrading to Next.js 13 does not require using the new App Router. You can continue using pages with new features that work in both directories, such as the updated Image component, Link component, Script component, and Font optimization.
<Image/> Component
Next.js 12 introduced new improvements to the Image Component with a temporary import: next/future/image. These improvements included less client-side JavaScript, easier ways to extend and style images, better accessibility, and native browser lazy loading.
In version 13, this new behavior is now the default for next/image.
There are two codemods to help you migrate to the new Image Component:
next-image-to-legacy-image codemod: Safely and automatically renames next/image imports to next/legacy/image. Existing components will maintain the same behavior.
next-image-experimental codemod: Dangerously adds inline styles and removes unused props. This will change the behavior of existing components to match the new defaults. To use this codemod, you need to run the next-image-to-legacy-image codemod first.
<Link> Component
The <Link> Component no longer requires manually adding an <a> tag as a child. This behavior was added as an experimental option in version 12.2 and is now the default. In Next.js 13, <Link> always renders <a> and allows you to forward props to the underlying tag.
For example:
 import Link from 'next/link'
 
// Next.js 12: `<a>` has to be nested otherwise it's excluded
<Link href="/about">
  <a>About</a>
</Link>
 
// Next.js 13: `<Link>` always renders `<a>` under the hood
// Next.js 13: `<Link>` always renders `<a>` under the hood
<Link href="/about">
  About
</Link>
To upgrade your links to Next.js 13, you can use the new-link codemod.
<Script> Component
The behavior of next/script has been updated to support both pages and app, but some changes need to be made to ensure a smooth migration:
Move any beforeInteractive scripts you previously included in _document.js to the root layout file (app/layout.tsx).
The experimental worker strategy does not yet work in app and scripts denoted with this strategy will either have to be removed or modified to use a different strategy (e.g. lazyOnload).
onLoad, onReady, and onError handlers will not work in Server Components so make sure to move them to a Client Component or remove them altogether.
Font Optimization
Font Optimization
Previously, Next.js helped you optimize fonts by inlining font CSS. Version 13 introduces the new next/font module which gives you the ability to customize your font loading experience while still ensuring great performance and privacy. next/font is supported in both the pages and app directories.
While inlining CSS still works in pages, it does not work in app. You should use next/font instead.
See the Font Optimization page to learn how to use next/font.
Migrating from pages to app
🎥 Watch: Learn how to incrementally adopt the App Router → YouTube (16 minutes).
Moving to the App Router may be the first time using React features that Next.js builds on top of such as Server Components, Suspense, and more. When combined with new Next.js features such as special files and layouts, migration means new concepts, mental models, and behavioral changes to learn.
We recommend reducing the combined complexity of these updates by breaking down your migration into smaller steps. The app directory is intentionally designed to work simultaneously with the pages directory to allow for incremental page-by-page migration.
The app directory supports nested routes and layouts. Learn more.
Use nested folders to define routes and a special page.js file to make a route segment publicly accessible. Learn more.
Special file conventions are used to create UI for each route segment. The most common special files are page.js and layout.js.
Use page.js to define UI unique to a route.
Use layout.js to define UI that is shared across multiple routes.
.js, .jsx, or .tsx file extensions can be used for special files.
You can colocate other files inside the app directory such as components, styles, tests, and more. Learn more.
Data fetching functions like getServerSideProps and getStaticProps have been replaced with a new API inside app. getStaticPaths has been replaced with generateStaticParams.
pages/_app.js and pages/_document.js have been replaced with a single app/layout.js root layout. Learn more.
pages/_error.js has been replaced with more granular error.js special files. Learn more.
pages/404.js has been replaced with the not-found.js file.
pages/api/* currently remain inside the pages directory.
Step 1: Creating the app directory
Update to the latest Next.js version (requires 13.4 or greater):
 npm install next@latest
Then, create a new app directory at the root of your project (or src/ directory).
Step 2: Creating a Root Layout
Create a new app/layout.tsx file inside the app directory. This is a root layout that will apply to all routes inside app.
app/layout.tsx export default function RootLayout({
  // Layouts must accept a children prop.
  // This will be populated with nested layouts or pages
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <html lang="en">
      <body>{children}</body>
    </html>
  )
}
The app directory must include a root layout.
The root layout must define <html>, and <body> tags since Next.js does not automatically create them
The root layout replaces the pages/_app.tsx and pages/_document.tsx files.
.js, .jsx, or .tsx extensions can be used for layout files.
To manage <head> HTML elements, you can use the built-in SEO support:
app/layout.tsx import { Metadata } from 'next'
 
export const metadata: Metadata = {
  title: 'Home',
export const metadata: Metadata = {
  title: 'Home',
  description: 'Welcome to Next.js',
}
Migrating _document.js and _app.js
If you have an existing _app or _document file, you can copy the contents (e.g. global styles) to the root layout (app/layout.tsx). Styles in app/layout.tsx will not apply to pages/*. You should keep _app/_document while migrating to prevent your pages/* routes from breaking. Once fully migrated, you can then safely delete them.
If you are using any React Context providers, they will need to be moved to a Client Component.
Migrating the getLayout() pattern to Layouts (Optional)
Next.js recommended adding a property to Page components to achieve per-page layouts in the pages directory. This pattern can be replaced with native support for nested layouts in the app directory.
See before and after exampleBeforecomponents/DashboardLayout.js export default function DashboardLayout({ children }) {
  return (
    <div>
      <h2>My Dashboard</h2>
      {children}
    </div>
  )
}pages/dashboard/index.js import DashboardLayout from '../components/DashboardLayout'
 
export default function Page() {
  return <p>My Page</p>
}
 
Page.getLayout = function getLayout(page) {
  return <DashboardLayout>{page}</DashboardLayout>
}After
Remove the Page.getLayout property from pages/dashboard/index.js and follow the steps for migrating pages to the app directory.
app/dashboard/page.js export default function Page() {
  return <p>My Page</p>
}
Move the contents of DashboardLayout into a new Client Component to retain pages directory behavior.
}
Move the contents of DashboardLayout into a new Client Component to retain pages directory behavior.
app/dashboard/DashboardLayout.js 'use client' // this directive should be at top of the file, before any imports.
 
// This is a Client Component
export default function DashboardLayout({ children }) {
  return (
    <div>
      <h2>My Dashboard</h2>
      {children}
    </div>
  )
}
Import the DashboardLayout into a new layout.js file inside the app directory.
app/dashboard/layout.js import DashboardLayout from './DashboardLayout'
 
// This is a Server Component
export default function Layout({ children }) {
  return <DashboardLayout>{children}</DashboardLayout>
}
You can incrementally move non-interactive parts of DashboardLayout.js (Client Component) into layout.js (Server Component) to reduce the amount of component JavaScript you send to the client.
Step 3: Migrating next/head
In the pages directory, the next/head React component is used to manage <head> HTML elements such as title and meta . In the app directory, next/head is replaced with the new built-in SEO support.
Before:
pages/index.tsx import Head from 'next/head'
 
export default function Page() {
  return (
    <>
      <Head>
        <title>My page title</title>
      </Head>
    </>
  )
}
After:
app/page.tsx import { Metadata } from 'next'
 
export const metadata: Metadata = {
  title: 'My Page Title',
}
 
export default function Page() {
  return '...'
}
See all metadata options.
Step 4: Migrating Pages
}
See all metadata options.
Step 4: Migrating Pages
Pages in the app directory are Server Components by default. This is different from the pages directory where pages are Client Components.
Data fetching has changed in app. getServerSideProps, getStaticProps and getInitialProps have been replaced for a simpler API.
The app directory uses nested folders to define routes and a special page.js file to make a route segment publicly accessible.
pages Directoryapp DirectoryRouteindex.jspage.js/about.jsabout/page.js/aboutblog/[slug].jsblog/[slug]/page.js/blog/post-1
We recommend breaking down the migration of a page into two main steps:
Step 1: Move the default exported Page Component into a new Client Component.
Step 2: Import the new Client Component into a new page.js file inside the app directory.