serverRuntimeConfigとpublicRuntimeConfigの違いを調べてみたのでメモしておきます。
Server Componentsでは呼び出せましたが、そもそも廃止されているようなので、代わりの方法も検討します。
serverRuntimeConfigとpublicRuntimeConfigの違い
サーバー側だけで使うものserverRuntimeConfig、クライアント側とサーバー側で使うものpublicRuntimeConfigなのですが。。。
設定して出力してみる(Server Components)
next.config.js
const nextConfig = {
reactStrictMode: true,
+ serverRuntimeConfig: {
+ // Will only be available on the server side
+ serverConfig: 'server'
+ },
+ publicRuntimeConfig: {
+ // Will be available on both server and client
+ publicConfig: 'public'
+ }
}
src/app/[locale]/components/Infomations.tsx
+ import getConfig from 'next/config'
+ const { publicRuntimeConfig, serverRuntimeConfig } = getConfig()
+ console.log(publicRuntimeConfig, serverRuntimeConfig)
+ const config = getConfig()
+ console.log(config)
ターミナル
{ publicConfig: 'public' } { serverConfig: 'server' } { configFileName: 'next.config.js', publicRuntimeConfig: { publicConfig: 'public' }, serverRuntimeConfig: { serverConfig: 'server' } }
Client Componentsで出力してみる
src/app/[locale]/components/Infomations.tsx
+ 'use client'
Unhandled Runtime Error TypeError: Cannot destructure property 'publicRuntimeConfig' of 'next_config__WEBPACK_IMPORTED_MODULE_2___default(...)(...)' as it is undefined. > 11 | const { publicRuntimeConfig, serverRuntimeConfig } = getConfig() | ^
serverRuntimeConfigだけでなく、publicRuntimeConfigも呼べない。
src/app/[locale]/components/Infomations.tsx
- const { publicRuntimeConfig, serverRuntimeConfig } = getConfig()
- console.log(publicRuntimeConfig, serverRuntimeConfig)
ターミナル
{ serverRuntimeConfig: { serverConfig: 'server' }, publicRuntimeConfig: { publicConfig: 'public' } }
ブラウザのコンソール
undefined
Client Componentsからは取得できない。
Server Componentsから渡してあげる
Server Components: src/app/[locale]/page.tsx
+ import getConfig from 'next/config'
+ const { publicRuntimeConfig, serverRuntimeConfig } = getConfig()
return (
- <Infomations />
+ <Infomations publicConfig={publicRuntimeConfig.publicConfig} serverConfig={serverRuntimeConfig.serverConfig} />
Client Components: src/app/[locale]/components/Infomations.tsx
+ 'use client'
- export default function Infomations() {
+ export default function Infomations({ publicConfig, serverConfig }: { publicConfig: any, serverConfig: any }) {
return (
+ publicConfig: {publicConfig}<br/>
+ serverConfig: {serverConfig}
publicConfig: public serverConfig: server
やっぱり、両方出てしまう。。。
この機能は廃止されました
next.config.js Options: Runtime Config | Next.js
Warning: This feature is deprecated. We recommend using environment variables instead, which also can support reading runtime values. この機能は廃止されました。代わりに、ランタイム値の読み取りもサポートできる 環境変数を使用することをお勧めします。
選択肢と方針
Configuring: Environment Variables | Next.js
.envでNEXT_PUBLIC_
を付けると、Client Componentsからも参照できる。
.env.development, .env.productionで環境毎の情報が持てる。
→ 環境毎に異なる値(APIドメイン等)は、コンテナの環境変数や.bashrcで設定したのを使うので、.env.developmentを使う。
→ 環境で変わらない値(APIのURI等)は、変更出来ない方がいいので.envじゃない方法にしたい。
.env.local, .env.development.local, .env.production.localは、デフォルトではGitから除外されていて、シークレットな値を入れる想定。
→ AWSならParameter StoreかSecrets Managerを使うので不要。
next.config.js Options: env | Next.js
next.config.jsでenvを定義できる
→ .envに書かなくても、process.envで取得できる。
上記と同様に、Client Componentsからも参照するには、NEXT_PUBLIC_
を付ける必要がある。
stringしか設定できない。booleanやnumberは、ts(2322)の警告が出る。
→ .envから取得できるのもstring(ECSの環境変数も文字列)なので、.envを使うのと変わらない。
config.tsを作って、importして使う
実装するので自由度が高い。やりたい事。
・.envの値の型を変えたい
・.env未設定時、デフォルト値で上書きしたい
・.envで変更できない値を持ちたい。
・objectも持てる。
方針に従って修正
.env → .env.development
コンテナの環境変数や.bashrcで設定するので、ローカルだけになるようにファイル名を変更。
Client Componentsからも参照できるように、NEXT_PUBLIC_を追加。
- SERVER_ENV=development # or test or staging or production
+ NEXT_PUBLIC_SERVER_ENV='development' # or test or staging or production
+ NEXT_PUBLIC_DEBUG=true
src/config.ts
i18n対応で、同名のを使っていたので、そちらをsrc/i18n.config.tsに変更してから作成。
export const config = {
serverEnv: process.env.NEXT_PUBLIC_SERVER_ENV || 'production',
debug: process.env.NEXT_PUBLIC_DEBUG === 'true'
}
src/app/[locale]/layout.tsx
+ import { config } from '@/config'
- template: `%s - ${t('app_name')}${t(`env_name.${process.env.SERVER_ENV || 'production'}`)}`
+ template: `%s - ${t('app_name')}${t(`env_name.${config.serverEnv}`)}`
- <Link href="/">{`${t('app_name')}${t('sub_title')}${t(`env_name.${process.env.SERVER_ENV || 'production'}`)}`}</Link>
+ <Link href="/">{`${t('app_name')}${t('sub_title')}${t(`env_name.${config.serverEnv}`)}`}</Link>
src/app/[locale]/page.tsx
+ import { config } from '@/config'
- absolute: `${t('app_name')}${t(`env_name.${process.env.SERVER_ENV || 'production'}`)}`
+ absolute: `${t('app_name')}${t(`env_name.${config.serverEnv}`)}`
src/app/[locale]/components/Infomations.tsx
Client Componentsで表示されるかのテストをします。
+ 'use client'
+ import { config } from '@/config'
return (
+ {String(config.debug)}
メモ: 文字列じゃないのを入れても表示されず、Warningが出ます。
Warning: Failed prop type: Invalid prop `children` supplied to `ForwardRef(Typography)`, expected a ReactNode.
今回のコミット内容
呼び出し(process.env → config)がスッキリして、
文字列以外の型やデフォルト値も使えるようになりました。
変更不要な設定値や、オブジェクトも簡単に入れられます。