😇

Next.jsのfrontendにSentryを設置したいんだが環境変数経由でのセットアップがややこしい

2024/01/29に公開

https://github.com/getsentry/sentry-javascript/issues/4070
このIssueに書いてあるような感じでNext.jsのfrontendにSentryをセットアップしようとしていたら

(以下、上記Issueからの転載)
sentry.client.config.js

import * as Sentry from '@sentry/nextjs';
import getConfig from 'next/config';

const { publicRuntimeConfig } = getConfig();

const SENTRY_DSN = process.env.SENTRY_DSN || process.env.NEXT_PUBLIC_SENTRY_DSN;

Sentry.init({
  dsn:
    SENTRY_DSN ||
    'https://foo@bar.ingest.sentry.io/1234567',
  tracesSampleRate: process.env.SENTRY_TRACES_SAMPLE_RATE || 0,
  environment: publicRuntimeConfig.SENTRY_ENVIRONMENT || 'development',
});

どうもprocess.env.SENTRY_DSNが(NEXT_PUBLIC_SENTRY_DSNも)見当たらなくてセットアップに詰まった。

Next.jsドキュメントを見ると、Next.js v9.4.0からは.env.xxxで環境変数がサポートされ、NEXT_PUBLIC_プレフィックスがついているもののみFrontend側に共有されるという。
https://nextjs.org/docs/pages/building-your-application/configuring/environment-variables

.envファイルを用意できればよかったのだが、デプロイスクリプトの流れ上ファイル切り替えがすこしめんどくさかった。(環境ごとの設定変更を吸収するのが)

以下のDiscussionをみると、Next.jsのビルド時にビルド環境の環境変数を読み込んでnext.config.js経由で埋め込めると。
https://github.com/vercel/next.js/discussions/30818
https://nextjs.org/docs/app/api-reference/next-config-js/env
(以下、Discussionから転載)
next.config.js

module.exports = {
  env: {
    CONFIG_FOO: process.env.CONFIG_FOO
  }
}

に対して

next build
next start

だとクライアント側で

Page: CONFIG_FOO undefined

になるが、ビルド時に環境変数を与えると

NEXT_PUBLIC_FOO=BUILDTIME CONFIG_FOO=BUILDTIME FOO=BUILDTIME next build
next start
Page: CONFIG_FOO BUILDTIME

ちゃんと埋め込まれている。NEXT_PUBLIC_がついていなくてもfrontend側で取れているのは、getServerSidePropsを使って取得しているからだろう。

ということで、自分の場合はDockerfile経由でnext buildを行っているので、Dockerfile内に

ENV NEXT_PUBLIC_SENTRY_DSN=https://foo@bar.ingest.sentry.io/1234567

RUN next build

として(デプロイスクリプトで適当に書き換え)

next.config.js

module.exports = {
  env: {
    NEXT_PUBLIC_SENTRY_DSN: process.env.NEXT_PUBLIC_SENTRY_DSN
  }
}

sentry.client.config.js

Sentry.init({
  dsn: process.env.NEXT_PUBLIC_SENTRY_DSN
});

この形で連携することができた (もしかするとNEXT_PUBLIC をつけていればnext.config.js経由でなくても良いのかもしれない)。

以上、とりあえずメモでした。

Discussion