$ cnpm install monkey-core
Visit to get started with Next.js.
The below readme is the documentation for the
canary (prerelease) branch. To view the documentation for the latest stable Next.js version visit nextjs.org/docs.
<head>
<Link>
onClick
hrefto its child
popstate
<Link>
<App>
<Document>
renderPage
pages
next export
npx create-next-app
(npx comes with npm 5.2+ and higher, see instructions for older npm versions)
Install it in your project:
and then just run
npm run dev and go to. To use another port, you can run
npm run dev -- -p <your port here>.
So far, we get:
./pages/
./public/is mapped to
/(given you create a
./public/directory inside your project)
Every
import you declare gets bundled and served with each page. That means pages never load unnecessary code!
import cowsay from 'cowsay-browser' function CowsayHi() { return <pre>{cowsay.say({ text: 'hi there!' })}</pre> } export default CowsayHi
We bundle styled-jsx to provide support for isolated scoped CSS. The aim is to support "shadow CSS" similar to Web Components, which unfortunately do not support server-rendering and are JS-only..
It's possible to use any existing CSS-in-JS solution. The simplest one is inline styles:
function HiThere() { return <p style={{ color: 'red' }}>hi there</p> } export default HiThere
To use more sophisticated CSS-in-JS solutions, you typically have to implement style flushing for server-side rendering. We enable this by allowing you to define your own custom
<Document> component that wraps each page.
To support importing
.css,
.scss,
.less or
.styl files you can use these modules, which configure sensible defaults for server rendered applications.
Create a folder called
public in your project root directory. From your code you can then reference those files starting from the baseURL
/
function MyImage() { return <img src="/my-image.png" alt="my image" /> } export default MyImage
Note: Don't name the
public directory anything else. The name can't be changed and is the only directory that Next.js uses for serving static assets.
Defining routes by using predefined paths is not always enough for complex applications, in Next.js you can add brackets to a page (
[param]) to create a dynamic route (a.k.a. url slugs, pretty urls, et al).
Consider the following page
pages/post/[pid].js:
import { useRouter } from 'next/router' const Post = () => { const router = useRouter() const { pid } = router.query return <p>Post: {pid}</p> } export default Post
Any route like
/post/1,
pages/post/[pid].js.
The matched path parameter will be sent as a query parameter to the page.
For example, the route
query object:
{ pid: 'abc' }.
Similarly, the route
query object:
{ foo: 'bar', pid: 'abc' }.
Note: Multiple dynamic route segments work the same way.
For example,
pages/post/[pid]/[comment].jswould match
/post/1/a-comment. Its
queryobject would be:
{ pid: '1', comment: 'a-comment' }.
A
<Link> for
<Link href="/post/[pid]" as="/post/abc"> <a>First Post</a> </Link>
href: the path inside
pagesdirectory.
as: the path that will be rendered in the browser URL bar.
As
href is a filesystem path, it shouldn't change at runtime, instead, you will probably need to change
as
dynamically according to your needs. Here's an example to create a list of links:
const pids = ['id1', 'id2', 'id3'] { pids.map(pid => ( <Link href="/post/[pid]" as={`/post/${pid}`}> <a>Post {pid}</a> </Link> )) }
You can read more about
<Link>here.
However, if a query and route param name are the same, route parameters will override the matching query params.
For example,
query object:
{ pid: 'abc' }.
Note: Predefined routes take precedence over dynamic routes. For example, if you have
pages/post/[pid].jsand
pages/post/create.js, the route
/post/createwill be matched by
pages/post/create.jsinstead of the dynamic route (
[pid]).
Note: Pages that are statically optimized by automatic static optimization will be hydrated without their route parameters provided (
querywill be empty, i.e.
{}). After hydration, Next.js will trigger an update to your application to provide the route parameters in the
queryobject. If your application cannot tolerate this behavior, you can opt-out of static optimization by capturing the query parameter in
getInitialProps.
Note: If deploying to ZEIT Now dynamic routes will work out-of-the-box. You do not need to configure custom routes in a
now.jsonfile.
If you are new to ZEIT Now, you can learn how to deploy a Next.js app to it in the Deploying a Next.js App Learn section.
<head>
We expose a built-in component for appending elements to the
<head> of the page.
import Head from 'next/head'
In this case only the second
<meta name="viewport" /> is rendered.
Note: The contents of
<head> get cleared upon unmounting the component, so make sure each page completely defines what it needs in
<head>, without making assumptions about what other pages added.
Note:
<title> and
<meta> elements need to be contained as direct children of the
<Head> element, or wrapped into maximum one level of
<React.Fragment>, otherwise the metatags won't be correctly picked up on clientside navigation.
When you need state, lifecycle hooks or initial data population you can export a function component that uses Hooks or a class component.
Using a function component:
import fetch from 'isomorphic-unfetch' function Page({ stars }) { return <div>Next stars: {stars}</div> } Page.getInitialProps = async ({ req }) => { const res = await fetch('') const json = await res.json() return { stars: json.stargazers_count } } export default Page
Using a class component:
import React from 'react' class HelloUA extends React.Component { static async getInitialProps({ req }) { const userAgent = req ? req.headers['user-agent'] : navigator.userAgent return { userAgent } } render() { return <div>Hello World {this.props.userAgent}</div> } } export default HelloUA.
-
getInitialPropscan not be used in children components. Only in
pages.
- If you are using some server only modules inside
getInitialProps, make sure to import them properly, otherwise, it'll slow down your app.)
err- Error object if any error is encountered during the rendering
Next.js does not ship a routes manifest with every possible route in the application, so the current page is not aware of any other pages on the client side. All subsequent routes get lazy-loaded, for scalability sake.
<Link>
Client-side transitions between routes can be enabled via a
<Link> component.
This component is not required for navigations to static pages that require a hard refresh, like when using AMP.
Basic Example
Consider these two pages:
// pages/index.js import Link from 'next/link' function Home() { return ( <> <ul> <li>Home</li> <li> <Link href="/about"> <a>About Us</a> </Link> </li> </ul> <h1>This is our homepage.</h1> </> ) } export default Home
// pages/about.js import Link from 'next/link' function About() { return ( <> <ul> <li> <Link href="/"> <a>Home</a> </Link> </li> <li>About Us</li> </ul> <h1>About</h1> <p>We are a cool company.</p> </> ) } export default About
Note: if passing a functional component as a child of
<Link> you will need to wrap it in
React.forwardRef
Example with
React.forwardRef
import React from 'react' import Link from 'next/link' // `onClick`, `href`, and `ref` need to be passed to the DOM element // for proper handling const MyButton = React.forwardRef(({ onClick, href }, ref) => ( <a href={href} onClick={onClick} ref={ref}> Click Me </a> )) export default () => ( <> <Link href="/another"> <MyButton /> </Link> </> )
Custom routes (using props from URL)
If you find that your use case is not covered by Dynamic Routing then you can create a custom server and manually add dynamic routes.
Example:
Consider you have the URL
/post/:slug.
You created
pages/post.js:
import { useRouter } from 'next/router' const Post = () => { const router = useRouter() const { slug } = router.query return <p>My Blog Post: {slug}</p> } export default Post
You add the route to
express (or any other server) on
server.js file (this is only for SSR). This will route the url
/post/:slug to
pages/post.js and provide
slug as part of the
query object to the page.
server.get('/post/:slug', (req, res) => { return app.render(req, res, '/post', { slug: req.params.slug }) })
For client side routing, use
next/link:
<Link href="/post?slug=something" as="/post/something">
href: the path inside
pagesdirectory
as: the path used by your server routes
Client-side routing behaves exactly like the browser:
getInitialProps, data is fetched. If an error occurs,
_error.jsis rendered.
pushStateis performed and the new component is rendered.
To inject the
pathname,
query or
asPath in your component, you can use the useRouter hook, or withRouter for class components.
The component
<Link> can also receive a URL object and it will automatically format it to create the URL string.
// pages/index.js import Link from 'next/link' function Home() { return ( <div> Click{' '} <Link href={{ pathname: '/about', query: { name: 'Zeit' } }}> <a>here</a> </Link>{' '} to read more </div> ) } export default Home' function Home() { return ( <div> Click{' '} <Link href="/about" replace> <a>here</a> </Link>{' '} to read more </div> ) } export default Home
onClick
<Link> supports any component that supports the
onClick event. In case you don't provide an
<a> tag, it will only add the
onClick event handler and won't pass the
href property.
// pages/index.js import Link from 'next/link' function Home() { return ( <div> Click{' '} <Link href="/about"> <img src="/static/image.png" alt="image" /> </Link> </div> ) } export default Home
hrefto site’s SEO.
import Link from 'next/link' import Unexpected_A from 'third-library' function NavLink({ href, name }) { return ( <Link href={href} passHref> <Unexpected_A>{name}</Unexpected_A> </Link> ) } export default NavLink>
You can also do client-side page transitions using
next/router:
import Router from 'next/router' function ReadMore() { return ( <div> Click <span onClick={() => Router.push('/about')}>here</span> to read more </div> ) } export default ReadMore the function you pass into
beforePopState returns
false,.
You can use a URL object the same way you use it in a
<Link> component to
push and
replace a URL.
import Router from 'next/router' const handler = () => { Router.push({ pathname: '/about', query: { name: 'Zeit' }, }) } function ReadMore() { return ( <div> Click <span onClick={handler}>here</span> to read more </div> ) } export default ReadMore
This uses the same exact parameters as in the
<Link> component. The first parameter maps to
href while the second parameter maps to
as in the
<Link> component as documented here., or a route load is cancelled
beforeHistoryChange(url)- Fires just before changing the browser's history
hashChangeStart(url)- Fires when the hash will change but not the page
hashChangeComplete(url)- Fires when the hash has changed but not the page
Here
urlis the URL shown in the browser. If you call
Router.push(url, as)(or similar), then the value of
urlwill be
as.
Here's how to properly listen to the router event
routeChangeStart:
const handleRouteChange =!`) } })
Note: Using router events in
getInitialPropsis discouraged as it may result in unexpected behavior.
Router events should be registered when a component mounts (
useEffector
componentDidMount/
componentWillUnmount) or imperatively when an event happens.
useEffect(() => { const handleRouteChange = url => { console.log('App is changing to: ', url) } Router.events.on('routeChangeStart', handleRouteChange) return () => { Router.events.off('routeChangeStart', handleRouteChange) } }, [])
Shallow routing allows you to change the URL without running
getInitialProps. You'll receive the updated
pathname and the
query via the
router prop (injected by using
useRouter or
withRouter),.router.query inside the
Component (make sure you are using
withRouter around your
Component to inject the
router prop).
You can watch for URL changes via
componentDidUpdate hook as shown below:
componentDidUpdate(prevProps) { const { pathname, query } = this.props.router // verify props have changed to avoid an infinite loop if (query.id !== prevProps.router.query.id) { //.
If you want to access the
router object inside any functional component in your app, you can use the
useRouter hook, here's how to use it:
import { useRouter } from 'next/router' export default function ActiveLink({ children, href }) { const router = useRouter() const style = { marginRight: 10, color: router.pathname === href ? 'red' : 'black', } const handleClick = e => { e.preventDefault() router.push(href) } return ( <a href={href} onClick={handleClick} style={style}> {children} </a> ) }
Note:
useRouteris a React hook, meaning it cannot be used with classes. You can either use
withRouter(a higher order component) or wrap your class in a functional component.
The above
router object comes with an API similar to
next/router.
If useRouter is not the best fit for you,
withRouter can also add the same
router object to any component, here's how to use it:
import { withRouter } from 'next/router' function Page({ router }) { return <p>{router.pathname}</p> } export default withRouter(Page)
⚠️ This is a production only feature ⚠️.
Automatic prefetching is disabled if your device is connected with 2G network or Save-Data header is
on.
<link rel="preload">is used for prefetching. Sometimes browsers will show a warning if the resource is not used within 3 seconds, these warnings can be ignored as per.
<Link>
<Link> will automatically prefetch pages in the background as they appear in the view. If certain pages are rarely visited you can manually set
prefetch to
false, here's how:
<Link href="/about" prefetch={false}> <a>About</a> </Link>
Most prefetching needs are addressed by
<Link />, but we also expose an imperative API for advanced usage:
import { useRouter } from 'next/router' export default function MyLink() { const router = useRouter() return ( <> <a onClick={() => setTimeout(() => router.push('/dynamic'), 100)}> A route transition will happen after 100ms </a> {// and we can prefetch it! router.prefetch('/dynamic')} </> ) }
router methods should be only used inside the client side of your app though. In order to prevent any error regarding this subject use the imperative
prefetch method in the
useEffect() hook:
import { useRouter } from 'next/router' export default function MyLink() { const router = useRouter() useEffect(() => { router.prefetch('/dynamic') }) return ( <a onClick={() => setTimeout(() => router.push('/dynamic'), 100)}> A route transition will happen after 100ms </a> ) }
You can also add it to the
componentDidMount() lifecycle method when using
React.Component:
import React from 'react' import { withRouter } from 'next/router' class MyLink extends React.Component { componentDidMount() { const { router } = this.props router.prefetch('/dynamic') } render() { const { router } = this.props return ( <a onClick={() => setTimeout(() => router.push('/dynamic'), 100)}> A route transition will happen after 100ms </a> ) } } export default withRouter(MyLink)
API routes provide a straightforward solution to build your API with Next.js.
Start by creating the
api/ folder inside the
./pages/ folder.
Every file inside
./pages/api is mapped to
/api/*.
For example,
./pages/api/posts.js is mapped to the route
/api/posts.
Here's an example API route file:
export default (req, res) => { res.setHeader('Content-Type', 'application/json') res.statusCode = 200 res.end(JSON.stringify({ name: 'Nextjs' })) }
req refers to NextApiRequest which extends http.IncomingMessage
res refers to NextApiResponse which extends http.ServerResponse
For API routes there are built-in types
NextApiRequest and
NextApiResponse, which extend the
Node.js request and response objects.
import { NextApiRequest, NextApiResponse } from 'next' export default (req: NextApiRequest, res: NextApiResponse) => { res.status(200).json({ title: 'Next.js' }) }
To handle different HTTP methods for API calls you can access
req.method in your resolver function:
export default (req, res) => { if (req.method === 'POST') { // Process your POST request } else { // Handle the rest of your HTTP methods } }
Note: API Routes do not specify CORS headers, so they'll be same-origin only by default. You can customize this behavior by wrapping your export with CORS middleware. We provide an example of this below.
API Routes do not increase your client-side bundle size. They are server-side only bundles.
API pages support dynamic routing, so you can use all benefits mentioned already above.
Consider the following page
./pages/api/post/[pid].js, here is how you get parameters inside the resolver method:
export default (req, res) => { const { query: { pid }, } = req res.end(`Post: ${pid}`) }
API routes provides built in middlewares which parse the incoming
req.
Those middlewares are:
req.cookies- an object containing the cookies sent by the request. Defaults to
{}
req.query- an object containing the query string. Defaults to
{}
req.body- an object containing the body parsed by
content-type, or
nullif no body is sent
Body parsing is enabled by default with a size limit of
1mb for the parsed body.
You can opt-out of automatic body parsing if you need to consume it as a
Stream:
// ./pages/api/my-endpoint.js export default (req, res) => { // ... } export const config = { api: { bodyParser: false, }, }
You can adjust size of parsed body by adding
sizeLimit key to
bodyParser, supported values are by bytes library.
// ./pages/api/my-endpoint.js export default (req, res) => { // ... } export const config = { api: { bodyParser: { sizeLimit: '1mb', }, }, }
As an added bonus, you can also use any Micro compatible middleware!
For example, configuring CORS for your API endpoint can be done leveraging
micro-cors.
First, install
micro-cors:
npm i micro-cors # or yarn add micro-cors
Then, import
micro-cors and configure it. Finally, wrap your exported function in the middleware:
import Cors from 'micro-cors' const cors = Cors({ allowMethods: ['GET', 'HEAD'], }) function Endpoint(req, res) { res.json({ message: 'Hello Everyone!' }) } export default cors(Endpoint)
We're providing a set of Express.js-like methods to improve the developer experience and increase the speed of creating new API endpoints:
export default (req, res) => { res.status(200).json({ name: 'Next.js' }) }
res.status(code)- a function to set the status code.
codemust be a valid HTTP status code
res.json(json)- Sends a
JSONresponse.
jsonmust be a valid
JSONobject
res.send(body)- Sends the HTTP response.
bodycan be a
string, an
objector a
Buffer.
Sometimes we need to set the
assetPrefix dynamically. This is useful when changing the
assetPrefix based on incoming requests.
For that, we can use
app.setAssetPrefix.
Here's an example usage of it:
const next = require('next') const http = require('http') const dev = process.env.NODE_ENV !== 'production' const app = next({ dev }) const handleNextRequests = app.getRequestHandler() app.prepare().then(() => { const server = new http.Server((req, res) => { // Add assetPrefix support based on the hostname if (req.headers.host === 'my-app.com') { app.setAssetPrefix('') } else { app.setAssetPrefix('') } handleNextRequests(req, res) }) server.listen(port, err => { if (err) { throw err } console.log(`> Ready on{port}`) }) })
By default Next.js will add
x-powered-by to the request headers. There's an optional way to opt-out of this:
// next.config.js module.exports = { poweredByHeader: false, }
Next.js supports ES2020 dynamic
import()')) function Home() { return ( <div> <Header /> <DynamicComponent /> <p>HOME PAGE is here!</p> </div> ) } export default Home
// components/hello.js export function Hello() { return <p>Hello!</p> }
import dynamic from 'next/dynamic' const DynamicComponent = dynamic(() => import('../components/hello').then(mod => mod.Hello) ) function Home() { return ( <div> <Header /> <DynamicComponent /> <p>HOME PAGE is here!</p> </div> ) } export default Home
import dynamic from 'next/dynamic' const DynamicComponentWithCustomLoading = dynamic( () => import('../components/hello2'), { loading: () => <p>...</p> } ) function Home() { return ( <div> <Header /> <DynamicComponentWithCustomLoading /> <p>HOME PAGE is here!</p> </div> ) } export default Home
import dynamic from 'next/dynamic' const DynamicComponentWithNoSSR = dynamic( () => import('../components/hello3'), { ssr: false } ) function Home() { return ( <div> <Header /> <DynamicComponentWithNoSSR /> <p>HOME PAGE is here!</p> </div> ) } export default Home
<App>
Next.js uses the
App component to initialize pages. You can override it and control the page initialization. Which allows you to do amazing things like:
To override, create the
./pages/_app.js file and override the App class as shown below:
function MyApp({ Component, pageProps }) { return <Component {...pageProps} /> } // Only uncomment this method if you have blocking data requirements for // every single page in your application. This disables the ability to // perform automatic static optimization, causing every page in your app to // be server-side rendered. // // MyApp.getInitialProps = async (appContext) => { // // calls page's `getInitialProps` and fills `appProps.pageProps` // const appProps = await App.getInitialProps(appContext); // // return { ...appProps } // } export default MyApp
Note: Adding a custom
getInitialPropsin App will affect Automatic Static Optimization
<Document>
A custom
<Document> is commonly used to augment your application's
<html> and
<body> tags.
This is necessary because Next.js pages skip the definition of the surrounding document's markup.
This allows you to support Server-Side Rendering for CSS-in-JS libraries like styled-components or emotion. Note, styled-jsx is included in Next.js by default.
A custom
<Document> can also include
getInitialProps for expressing asynchronous server-rendering data requirements.
Note:
<Document>'s
getInitialPropsfunction is not called during client-side transitions, nor when a page is automatically statically optimized.
Note: Make sure to check if
ctx.req/
ctx.resare defined in
getInitialProps. These variables will be
undefinedwhen a page is being statically exported for
next exportor automatic static optimization.
To use a custom
<Document>, you must create a file at
./pages/_document.js and extend the
Document class:
// _document is only rendered on the server side and not on the client side // Event handlers like onClick can't be added to this file // ./pages/_document.js import Document, { Html, Head, Main, NextScript } from 'next/document' class MyDocument extends Document { static async getInitialProps(ctx) { const initialProps = await Document.getInitialProps(ctx) return { ...initialProps } } render() { return ( <Html> <Head /> <body> <Main /> <NextScript /> </body> </Html> ) } } export default MyDocument
All of
<Html>,
<Head />,
<Main /> and
<NextScript /> are required for page to be properly rendered.
Note: React-components outside of
<Main /> will not be initialised by the browser. Do not add application logic here. If you need shared components in all your pages (like a menu or a toolbar), take a look at the
<App> component instead..
renderPage
???? It should be noted that the only reason you should be customizing
renderPage is for usage with css-in-js libraries
that need to wrap the application to properly work with server-rendering. ????
404 or 500 errors are handled both client and server side by a default component
error.js. If you wish to override it, define a
_error.js in the pages folder:
⚠️ The
pages/_error.js component is only used in production. In development you get an error with call stack to know where the error originated from. ⚠️
import React from 'react' function Error({ statusCode }) { return ( <p> {statusCode ? `An error ${statusCode} occurred on server` : 'An error occurred on client'} </p> ) } Error.getInitialProps = ({ res, err }) => { const statusCode = res ? res.statusCode : err ? err.statusCode : 404 return { statusCode } } export default Error
If you want to render the built-in error page you can by using
next/error:
import React from 'react' import Error from 'next/error' import fetch from 'isomorphic-unfetch' const Page = ({ errorCode, stars }) => { if (errorCode) { return <Error statusCode={errorCode} /> } return <div>Next stars: {stars}</div> } Page.getInitialProps = async () => { const res = await fetch('') const errorCode = res.statusCode > 200 ? res.statusCode : false const json = await res.json() return { errorCode, stars: json.stargazers_count } } export default Page
If you have created a custom error page you have to import your own
_errorcomponent from
./_errorinstead of
next/error.
The Error component also takes
title as a property if you want to pass in a text message along with a
statusCode. */ } }
You can specify a name to use for a custom build directory. For example, the following config will create a
build folder instead of a
.next folder. If no configuration is specified then next will create a
.next folder.
// next.config.js module.exports = { distDir: 'build', }
You can disable etag generation for HTML pages depending on your cache strategy. If no configuration is specified then Next will generate etags for every page.
// next.config.js module.exports = { generateEtags: false, }.
pages
Aimed at modules like
@next/mdx, that add support for pages ending with
.mdx.
pageExtensions allows you to configure the extensions looked for in the
pages directory when resolving pages.
// next.config.js module.exports = { pageExtensions: ['mdx', 'jsx', 'js'], }' }, } }, }
You can pass any node arguments to
next CLI command.
NODE_OPTIONS="--throw-deprecation" next NODE_OPTIONS="-r esm" next NODE_OPTIONS="--inspect" next
Some commonly asked for features are available as modules:
Warning: The
webpackfunction is executed twice, once for the server and once for the client. This allows you to distinguish between client and server configuration using the
isServerproperty.
Multiple configurations can be combined together with function composition. For example:
const withMDX = require('@next/mdx') const withSass = require('@zeit/next-sass') module.exports = withMDX( withSass({ webpack(config, options) { // Further custom configuration here return config }, }) ) config }, }
The second argument to
webpack is an object containing properties useful when customizing its configuration:
buildId-
Stringthe build id used as a unique identifier between builds
dev-
Booleanshows if the compilation is done in development mode
isServer-
Booleanshows if the resulting configuration will be used for server side (
true), or client side compilation (
false)
defaultLoaders-
ObjectHolds loader objects Next.js uses internally, so that you can use them in custom configuration
babel-
Objectthe
babel-loaderconfiguration for Next.js
Example usage of
defaultLoaders.babel:
// Example next.config.js for adding a loader that depends on babel-loader // This source was taken from the @next/mdx plugin source: // module.exports = { webpack: (config, options) => { config.module.rules.push({ test: /\.mdx/, use: [ options.defaultLoaders.babel, { loader: '@mdx-js/loader', options: pluginOptions.options, }, ], }) return config }, }": [] }
The
next/babel preset includes everything needed to transpile React applications. This includes:
These presets / plugins should not be added to your custom
.babelrc. Instead, you can configure them on the
next/babel preset:
{ "presets": [ [ "next/babel", { "preset-env": {}, "transform-runtime": {}, "styled-jsx": {}, "class-properties": {} } ] ], "plugins": [] }
The
modules option on
"preset-env" should be kept to
false otherwise webpack code splitting is disabled.
There is a common need in applications to provide configuration values.
Next.js supports 2 ways of providing configuration:
The way build-time configuration works is by inlining the provided values into the Javascript bundle.
You can add the
env key in
next.config.js:
// next.config.js module.exports = { env: { customKey: 'value', }, }
This will allow you to use
process.env.customKey in your code. For example:
// pages/index.js function Index() { return <h1>The value of customKey is: {process.env.customKey}</h1> } export default Index
Warning: Note that it is not possible to destructure process.env variables due to the webpack
DefinePluginreplacing process.env.XXXX inline at build time.
// Will not work const { CUSTOM_KEY, CUSTOM_SECRET } = process.env AuthMethod({ key: CUSTOM_KEY, secret: CUSTOM_SECRET }) // Will work as replaced inline AuthMethod({ key: process.env.CUSTOM_KEY, secret: process.env.CUSTOM_SECRET })
Warning: Note that these options are not available when using
target: 'serverless'
Warning: Generally you want to use build-time configuration to provide your configuration. The reason for this is that runtime configuration adds rendering / initialization overhead and is incompatible with automatic static optimization.
The
next/config module gives your app access to the
publicRuntimeConfig and
serverRuntimeConfig stored in your
next.config.js.
Place any server-only runtime config under a
serverRuntimeConfig property.
Anything accessible to both client and server-side code should be under
publicRuntimeConfig.
Note: A page that relies on
publicRuntimeConfigmust use
getInitialPropsto opt-out of automatic static optimization. You can also de-optimize your entire application by creating a Custom
<App>with
getInitialProps.
// next.config.js module.exports = { serverRuntimeConfig: { // Will only be available on the server side mySecret: 'secret', secondSecret: process.env.SECOND_SECRET, // Pass through env variables }, function MyImage() { return ( <div>