I'm trying to use Next.js (9.5.2) for both Server Side Rendering and Static Site Generation. SSR works fine for me with assetPrefix. I am able to host all my static assets on CloudFront. However, I'm not sure what the best way is to host the static pages.
I am facing 2 issues.
assetPrefix
is not applied to SSG pages. so the link to JS/CSS will be something like this <link rel="preload" href="/_next/static/css/styles.31b6de8d.chunk.css" as="style"/>
assetPrefix
, how do I use Next.js Incremental Static Regeneration with fallback: true
in getStaticPath
. My understanding is that page will generated on the server side if the corresponding HTML is not found.Thanks everyone for helping.
Can I use a CDN for static assets? Yes! When you deploy your Next. js application to Vercel, your static assets are automatically detected and served by the Edge Network.
Next. js is a server-side rendering (SSR) tool, but with version 9.3, it also supports static site generation. The idea behind it is to create server-rendered React apps that require minimal to no configuration.
Next.js has two forms of pre-rendering: Static Generation and Server-side Rendering. The difference is in when it generates the HTML for a page. Static Generation (Recommended): The HTML is generated at build time and will be reused on each request.
The companion life-cycle method getStaticPaths of getStaticProps lets us use the data we have at build-time to specify which dynamic routes (like /pages/blog/[slug] ) we want to generate statically.
I have partial answers to my own question.
For issue 1:
The issue is my own fault. assetPrefix
worked with SSR but not for SSG because I didn't pass in environmental variables properly. In my situation, we have 2 different CDN URLs for production and staging. So I have something like the following in next.config.js
. Because MY_ENV
is passed in from PM2, which starts my app, it is guaranteed that MY_ENV
will always be available when Next.js needs to access next.config.js
.
// next.config.js
const isProd = process.env.MY_ENV === 'production';
const isStaging = process.env.MY_ENV === 'staging';
const isDevelopment = process.env.MY_ENV === 'development';
if (isProd) {
assetPrefix = 'https://mycdn.cloudfront.net/';
} else if (isStaging) {
assetPrefix = 'https://mycdn.cloudfront.net/staging';
}
However, when I run next build
for static pages, the build step doesn't use PM2 thus MY_ENV
is not available. To make it work, I need to run the build twice with different variables.
"build": "npm-run-all --parallel build:production build:staging",
"build:production": "MY_ENV=production next build",
"build:staging": "MY_ENV=staging next build",
For issue 2:
If I'm able to pre-generate all static pages. I can just put everything on CDN and they will work.
In my situation, ISR is a better fit. The way I get ISR to work is to ask the server to return the HTML for every request instead of hosting on the CDN. Since all other assets are hosted on the CDN, the performance is still pretty good and this solution works out well for my situation.
If you are like me who struggled a bit on this issue, I hope my answer helps you out.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With