NetlifyでNext.jsのSSR(serverless mode)を実行する
Next.js Advent Calendar 2020の5日目記事です。 Next.jsで作ったアプリケーションのデプロイといえばVercelですが、Netlifyもなかなか頑張っています。 公式にリリースされたプラグ […]
目次
Next.js Advent Calendar 2020の5日目記事です。
Next.jsで作ったアプリケーションのデプロイといえばVercelですが、Netlifyもなかなか頑張っています。
公式にリリースされたプラグインを使うことで、APIやserverless Modeでの実行などが可能ですので、軽く紹介します。
npm install -D next-on-netlify
NetlifyチームがリリースしているNetlify向けプラグインです。これを使うことで、Netlify上にデプロイしたNext.jsでもAPIやSSRが利用できます。
Install
npmにて公開されていますので、npm installで追加します。
$ npm install -D next-on-netlify
postbuildに指定
このプラグインはpostbuild
での実行が推奨されていますので、package.json
に指定します。
{
"name": "my-nextjs-app",
"scripts": {
"dev": "next",
"build": "next build",
"postbuild": "next-on-netlify"
target: “serverless”に変更
next.config.js
を更新して、ビルドのターゲットをserverless
に変更しておきましょう。
module.exports = {
target: "serverless"
}
netlify.toml
にビルド設定を定義
最後にNetlify側のビルド設定を定義します。
[build]
command = "npm run build"
functions = "out_functions"
publish = "out_publish"
あとはGitで変更をコミットし、pushしてNetlifyのビルドを実行するだけです。
getStaticPaths
のfallbackにも対応
このプラグインを入れると、NetlifyにホストしたNext.jsでもfallback
が利用できます。
下のコードは、WP APIから記事を取得して詳細ページを表示するサンプルpages/[id].tsx
です。
import Axios from 'axios'
import purify from "dompurify";
import Link from 'next/link'
import { useRouter } from 'next/router'
import { GetStaticPaths, GetStaticProps, NextPage } from "next";
export const Page: NextPage<{
post: {
title: {
rendered: string;
}
content: {
rendered: string;
}
}
}> = (props) => {
const router = useRouter()
if (router.isFallback) {
return <div>Loading...</div>
}
return (
<main>
<h1 dangerouslySetInnerHTML={{
__html: purify.sanitize(
props.post.title.rendered)
}} />
<div dangerouslySetInnerHTML={{
__html: purify.sanitize(
props.post.content.rendered)
}} />
</main>
)
}
export const getStaticPaths: GetStaticPaths = async () => {
const {data: posts} = await Axios.get('https://example.com/wp-json/wp/v2/posts?per_page=10')
return {
paths: posts.map(post => ({
params: {
id: `${post.id}`,
}
})),
fallback: true
}
}
export const getStaticProps: GetStaticProps = async ({params}) => {
const id = Array.isArray(params.id) ? params.id[0] : params.id
const {data: post} = await Axios.get('https://example.com/wp-json/wp/v2/posts/' + id)
return {
props: {
post
}
}
}
getStaticPaths
ではper_page=10
と最新10記事のみ生成させています。SSG(next export
)の場合は、ここで生成していない記事は、HTMLが生成されないために404となります。ですがnext-on-netlifyを利用した場合は、Netlifyでもfallback: trueを利用できますので、「なければSSRしてページ生成(= 都度SSG)」が可能になります。
next-on-netlifyはNetlify Functionを利用する
next-on-netlifyを利用してデプロイした場合、自動的にNetlify Functionがデプロイされます。
もちろんNetlify Functionには無料枠の制限がありますので、それを超えると実行できなくなります。
月間12.5万リクエスト、100実行時間までは無料です。fallbackで静的化されるであろうことを考えると「12.5万PVまでしか無料で使えない」というわけではなさそうですが、PVが多いサイトでは課金もしくはVercel or 自前Node.jsサーバーへの移行を検討することになるでしょう。
ちなみに課金はこんな感じです。1段階あげるだけで月25ドルいかれますが、利用枠も2000万リクエスト/1000実行時間まで一気に増えてくれます。
で、ISRは?
「段階的にサポート頑張ってます」という状況みたいです。現時点では。
普通にrevalidate
をgetStaticProps
に設定すると動いているように見える挙動をしてくれます。ただ、ISRについてのIssueがOpenなままなので、もしかすると何かしら未対応のものがあるかもしれません。
あと、Netlify Functionの実行数がどんどん増えそうなので、お財布が心配な方はあまりおすすめしないかもです。
Netlify or Vercel?
どちらにしてもいつまでも無料で使えるとは思わないようにしておくのが一番ストレスないかなとは思います。
Netlify FormやAccess Control・プラグインなどの機能をよく使っているのであればnext-on-netlifyで頑張りたくなりますし、そこまでNetlifyに思い入れもビジネス的な依存もないなら早めにVercelを検討してもよいかなという風に個人的には思っています。