next-on-netlify
is a utility for enabling server-side rendering in Next.js on Netlify. It wraps your application in a tiny compatibility layer, so that pages can use Netlify Functions to be server-side rendered.
- Build plugin @netlify/plugin-nextjs
- Plugin npm package
The future of Next.js on Netlify is growing beyond next-on-netlify
. The recommended path forward is to install @netlify/plugin-nextjs - a build plugin released and supported by the team behind next-on-netlify
.
The plugin relies on next-on-netlify
but offers a smoother experience, including:
- one-click, zero-config installation
- allowing custom functions and publish directories
See the plugin's README for more information. Our team's end goal is to make the Next.js on Netlify experience as seamless as possible.
Note: since next-on-netlify
will remain the primary source of logic for Next.js on Netlify, the existing next-on-netlify
setup will continue to work for users who prefer manual installation and configuration.
The plugin can be found on npm here.
npm install --save next-on-netlify
We must build our Next.js app as a serverless app. You can read more about serverless Next.js here.
It's super simple. Just create a next.config.js
file and write the following:
// next.config.js
module.exports = {
// Target must be serverless
target: "serverless",
};
If binaries are needed in the deployment the following configuration is needed (Prisma is an example):
// next.config.js
module.exports = {
// Target must be experimental-serverless-trace
// Your build time will be longer with this option
target: "experimental-serverless-trace",
};
The next-on-netlify package adds the next-on-netlify
command. When we run this command, some magic happens to prepare our Next.js app for hosting on Netlify*.
We want the next-on-netlify command to run after we build our Next.js application. So let's add a postbuild hook to our package.json file:
{
"name": "my-nextjs-app",
"scripts": {
"dev": "next",
"build": "next build",
"postbuild": "next-on-netlify"
},
...
}
*If you're curious about the "magic", check out the well-documented next-on-netlify.js
file.
We're almost done! We just have to tell Netlify how to build our Next.js app, where the functions folder is located, and which folder to upload to its CDN. We do that with a netlify.toml
file and the following instructions:
[build]
command = "npm run build"
functions = "out_functions"
publish = "out_publish"
Note: out_functions
and out_publish
are hard-coded into next-on-netlify.
These are not configurable at the moment.
If your project contains private submodules, in order to deploy it, you will need to:
-
Generate a Deploy Key in Netlify and add it to the relevant submodules so that they can be cloned during the deploy process.
-
Ensure the submodule remotes are set to SSH format (i.e.
git@github.com:owner/project.git
, nothttps://...
). Inside the submodule directory, the git remote can be updated with:# git remote set-url [remote] [url] git remote set-url origin git@github.com:owner/project.git
We're done. Let's deploy πππ
I recommend you still use next dev
to build and preview your application locally.
But if you want to emulate the Netlify deployment on your computer, you can also run next-on-netlify
locally and then use netlify-cli
to preview the result.
First, install the latest version of netlify-cli
(you can also look at package.json to see the version that next-on-netlify has been tested against):
npm install -g netlify-cli
Then, add the following [dev]
block to your netlify.toml
:
# netlify.toml
# [build]
# ...
[dev]
functions = "out_functions"
publish = "out_publish"
# We manually set the framework to static, otherwise Netlify automatically
# detects Next.js and redirects do not work.
# Read more: https://github.com/netlify/cli/blob/master/docs/netlify-dev.md#project-detection
framework = "#static"
Lastly, add the following lines to your .gitignore
:
# .gitignore
# Files generated by next-on-netlify command
/out_publish/
/out_functions/
Now you're all set.
From now on, whenever you want to preview your application locally, just run:
npm run build
: This will runnext build
to build your Next.js app andnext-on-netlify
to prepare your Next.js app for compatibility with Netlifynetlify dev
: This will emulate Netlify on your computer and let you preview your app onhttp://localhost:8888
.
Note:
Preview Mode is not yet available locally, running netlify dev
, for static pages without revalidate or fallback. This will be supported soon.
For now, Preview Mode is supported in production for all Next.js page types.
You can define custom redirects in a _redirects
and/or in your netlify.toml
file.
The precedence of these rules are:
_redirects
next-on-netlify
redirects
Currently, there is no support for redirects set in your netlify.toml
file.
Read more about Netlify redirects here.
next-on-netlify
creates one Netlify Function for each of your
SSR pages and API endpoints. It is currently not possible to create custom Netlify Functions. This feature is on our list to do.
You can use Netlify Identity with next-on-netlify
. For all pages with server-side rendering (getInitialProps*, getServerSideProps, and API routes), you can access the clientContext object via the req
parameter.
For example:
const Page = () => <p>Hello World!</p>;
export const getServerSideProps = async ({ req }) => {
// Get event and context from Netlify Function
const {
netlifyFunctionParams: { event, context },
} = req;
// Access Netlify identity
const { identity, user } = context.clientContext;
return {
props: {},
};
};
export default Page;
To access Netlify Identity from pages without server-side rendering, you can create a Next API route that performs identity-related logic:
export default async function getUser(req, res) {
// Get event and context from Netlify Function
const {
netlifyFunctionParams: { event, context },
} = req;
// Access Netlify identity
const { user } = context.clientContext;
// Respond with user object
res.json({ user });
}
* Note that pages using getInitialProps are only server-side rendered on initial page load and not when the user navigates client-side between pages.
Fallback pages behave differently with next-on-netlify
than they do with Next.js. On Next.js, when navigating to a path that is not defined in getStaticPaths
, it first displays the fallback page. Next.js then generates the HTML in the background and caches it for future requests.
With next-on-netlify
, when navigating to a path that is not defined in getStaticPaths
, it server-side renders the page and sends it directly to the user. The user never sees the fallback page. The page is not cached for future requests.
For more on this, see: Issue #7
Our existing solution for next/image is not very performant. We have performance improvements on our roadmap, dependent on internal work.
To get better performance now, we recommend using a cloud provider like Cloudinary (see the Next.js docs).
This package is maintained by Lindsay Levine, Finn Woelm, and Cassidy Williams.
π£ Shoutout to @mottox2 (a pioneer of hosting Next.js on Netlify) and @danielcondemarin (author of serverless-next.js for AWS). The two were big inspirations for this package.
π Big "thank you" to the following people for their contributions, support, and beta testing:
The following sites are built with next-on-netlify
:
opinionatedreact.com (via Twitter)
Create your own blog and deploy to Netlify!
Are you building something awesome with next-on-netlify
? π₯ Let us know and we will feature it here :)