Next.js

【Next.js】faviconを本番環境と開発環境で出し分ける。

やりたいこと

サイトのfaviconを本番環境では「💫」開発環境では「🚧」(ローカル環境)のように出し分けたい。

これでぱっと見でどの環境か区別することができるようになる。

⑴ faviconを準備する

publicフォルダ内にprod.svgdev.svgの2つのファイルを作成します。

  • 本番環境の「prod.svg」
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
    <text x="50%" y="50%" style="dominant-baseline:central;text-anchor:middle;font-size:90px;">💫</text>
</svg>
  • 開発(ローカル)環境の「dev.svg」
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
    <text x="50%" y="50%" style="dominant-baseline:central;text-anchor:middle;font-size:90px;">🚧</text>
</svg>

⑵ faviconの表示設定をする

faviconは<Head>内に<link rel="icon" href="[faviconにしたい画像]">を追加することで表示することができます。

今回は出し分けをしたいのでprocess.env.FAVICON_URLを指定して、環境ごとにこのprocess.env.FAVICON_URLが変わる処理を行なっていきます。

import React from 'react';
import Head from "next/head";


export default function Layout({ children }) {
    return (
        <div>
            <Head>
                <title>サイトタイトル</title>
                <link rel="icon" href={process.env.FAVICON_URL} />  // faviconの指定
            </Head>
            <div>
                { children }
            </div>
        </div>
    );
};

⑶ 本番環境か開発環境か区別する

環境変数を設定する

.envファイルにNODE_ENV=developmentを追加します。

これで開発環境の場合に、環境変数”NODE_ENV”は「development」になります。

NODE_ENV=development

(※本番環境のNODE_ENVにはproductionなどを入れましょう。)

環境変数によってfaviconのファイルを出し分ける

next.config.jsファイルで、環境変数NODE_ENVによって異なるFAVICON_URLに指定する処理を追加します。

module.exports = {
    env: {
        // 環境変数(.env)のNODE_ENVに応じて、FAVICON_URLを出し分け
        FAVICON_URL: process.env.NODE_ENV === `development` ? `dev.svg` : `prod.svg`,
    }
}

完成

これで開いているページが本番環境か開発環境か調べるために毎回URLを確認する、みたいな手間が省けます。

【NextAuth.js】ソーシャルログインの実装。

GoogleやTwitter、FacebookなどのSNSアカウントを使ってログインできる「ソーシャルログイン」の実装方法をまとめていきたいと思います。

使用するパッケージをインストールする

「next-auth」をインストール

$ npm install next-auth

プロバイダ側(SNSサービス側)の設定をする

ソーシャルログインを使うためには、GoogleやTwitterなど認証機能を使いたいサービスごとに「⑴ clientId」と「⑵ clientSecret」を事前に取得する必要があります。

Googleアカウントでログインしたい場合

Google Cloud Platform(GCP)で「clientId」と「clientSecret」の2つを取得します。

こちらは下記記事がとても参考になりました 。

Twitterアカウントでログインしたい場合

※分かり次第更新します。

Next.js側の設定をする

「.env」ファイル

プロバイダ側の設定で取得した「clientId」と「clientSecret」を.envファイル内記載します。

(もしトップディレクトリに.envファイルがない場合は作成してください。)

GOOGLE_CLIENT_ID=[取得したクライアントID]
GOOGLE_CLIENT_SECRET=[取得したクライアントシークレット]

「pages/api/[…nextauth].js」ファイル

pages/apiディレクトリ内に[...nextauth].jsを作成します。

[…nextauth].jsでは「使用するプロバイダの指定」をします。

import NextAuth from 'next-auth';
import GoogleProvider from 'next-auth/providers/google';

export default NextAuth({
    // 1: ログインに使用するプロバイダを指定
    providers: [
        GoogleProvider({
            clientId: process.env.GOOGLE_CLIENT_ID,
            clientSecret: process.env.GOOGLE_CLIENT_SECRET,
        }),
    ],
    secret: 'secret',
});

プロバイダごとに記載方法が異なるので、こちらの記事を参考に選んで記載してみてください。

「_app.js」ファイル

_app.jsのComponentをSessionProviderで囲います。

import {SessionProvider} from 'next-auth/react';

function MyApp({ Component, pageProps: { session, ...pageProps } }) {
    return(
        <SessionProvider session={session}>
            <Component {...pageProps} />
        </SessionProvider>
    )};
export default MyApp;

ログインボタンを作る

NextAuthでは、signIn()でログイン、signOut()でログアウトの処理を実装することができます。

import { useSession, signIn, signOut } from "next-auth/react"

export default function LoginButton(props) {
    // セッション情報を取得
    const { data: session } = useSession()

    return (
        {session ?  // ログイン判定
            <button onClick={() => signOut()}>ログアウト</button>:
            <button onClick={() => signIn()}>ログイン</button>
        }
    );
};

ログインユーザー情報をデータベースに保存する

ログインしたユーザー情報をデータベースへ保存したい場合は、「Prisma」を利用すると比較的簡単に実装することができます。

詳しくはこちらの記事を参考にしてみてください。

フォーム送信時「useRouter()」でリダイレクトができなかった原因。

フォーム送信時(onSubmit時)に、いろいろな処理をして、最後にリダイレクトをかける処理をするためにrouter.push()を活用しようとしました。

ですがrouter.push()が上手く動作せずに困ったので解決法メモです。

リダイレクトが動作しなかった原因

初歩的なミスで、<form>の動作を理解していなかったことが原因でした。

<form>の送信時には、デフォルトで<form action='〇〇'>で指定しているURLへリダイレクトがかかります。

下記コードの場合「onSubmitで実行される関数内のrouter.push()」より、「action=’〇〇’へのリダイレクト」が先に起きていました。

問題コード

import {useRouter} from "next/router";


export default function Redirect() {
    const router = useRouter();

    const handleSubmit = (e) => {
        router.push('/post');    // リダイレクトされない
    };
    
    return (
        <form action='' onSubmit={handleSubmit}>  // action=''へリダイレクトする
            <input type="text" />
            <button type="submit">送信ボタン</button>
        </form>
    );
};

解決方法

useRouter()でリダイレクトをかけるためには、form action='〇〇'によるリダイレクト処理を止める必要があります。

formのデフォルト処理を止めるにはe.preventDefault();が有効です。

解決コード

import {useRouter} from "next/router";


export default function Redirect() {
    const router = useRouter();

    const handleSubmit = (e) => {
        e.preventDefault();    // これでaction=''へのリダイレクト処理がストップできる
        router.push('/post');
    };
    
    return (
        <form action='' onSubmit={handleSubmit}>
            <input type="text" />
            <button type="submit">送信ボタン</button>
        </form>
    );
};

【NextAuth.js + Prisma】ログインしたユーザー情報をDBに保存する

NextAuth.jsとPrismaを使って、ログインしたユーザー情報をデータベースに保存する方法をまとめておきます。

今回は主に「Prismaの設定」に関する内容になります。NextAuth.jsの設定は完了している前提で書いているので、まだ設定できていない場合は先にNextAuth.jsの設定が必要になります。

後半にMySQLの場合の設定方法も詳しく記載しています。

⑴ 使用するパッケージをインストールする

$ npm install @prisma/client @next-auth/prisma-adapter
$ npm install prisma --save-dev

⑵ 接続先のデータベースを設定する

.envファイルの作成

Prismaで使用するデータベースの情報(URL等)を記載する.envファイルを作成します。

[project]
 ├ 〇〇
 ├ 〇〇
 └ .env  # 新規作成

.envファイルに接続先のデータベース情報を記載

接続先データベースの「URL」や「ユーザー名」などを.envファイル内に記載していきます。

PostgreSQLややMySQL、SQLiteなどのデータベースの種類によって記載方法が異なることがあるので確認してみてください。

DATABASE_URL=[データベースURL等]

⑶ データベース構造(スキーマ)等の設定する

$ npx prisma init

「prisma」フォルダを作成

[project]
 ├ 〇〇
 ├ 〇〇
 ├ .env
 └ prisma  # 新規作成

「schema.prisma」ファイルを作成

先ほど作成した「prisma」フォルダ内に「schema.prisma」作成します。

この「schema.prisma」は、データベースの構造を指定するファイルです。

[project]
 ├ 〇〇
 ├ 〇〇
 ├ .env
 └ prisma
   └ schema.prisma  # 新規作成

「schema.prisma」を編集

// =====================================
// 1_接続するデータベースの設定
// =====================================
datasource db {
    provider = "mysql"
    url      = [DATABASE_URL]
}


// =====================================
// 2_「npx prisma generate」で生成するものを指定
// =====================================
generator client {
    provider = "prisma-client-js"
}


// =====================================
// 3_作成するモデルを指定
// =====================================
// Accountモデル
model Account {
    id                 String  @id @default(cuid())
    userId             String
    type               String
    provider           String
    providerAccountId  String
    refresh_token      String?  @db.Text
    access_token       String?  @db.Text
    expires_at         Int?
    token_type         String?
    scope              String?
    id_token           String?  @db.Text
    session_state      String?

    user User @relation(fields: [userId], references: [id], onDelete: Cascade)

    @@unique([provider, providerAccountId])
}

// Sessionモデル
model Session {
    id           String   @id @default(cuid())
    sessionToken String   @unique @map("session_token")
    userId       String   @map("user_id")
    expires      DateTime
    user         User     @relation(fields: [userId], references: [id], onDelete: Cascade)

    @@map("sessions")
}

// Userモデル
model User {
    id            String    @id @default(cuid())
    name          String?
    email         String?   @unique
    emailVerified DateTime? @map("email_verified")
    image         String?
    accounts      Account[]
    sessions      Session[]

    @@map("users")
}

❶ 接続するデータベースの設定

「⑴データベースの種類(SQLite, progresql, MySQL, …)」と「⑵その接続先URL」を設定します。

// =====================================
// 1_接続するデータベースの設定
// =====================================

datasource db {
    provider = "mysql"
    url      = [DATABASE_URL]  # MySQLの接続先URLの書き方は後述
}

❷ 生成するクライアントの指定(Prisma Client)

// =====================================
// 2_「npx prisma generate」で生成するものを指定
// =====================================

generator client {
    provider = "prisma-client-js"
}

ここで生成するClientは、アプリ内で使用できるようになります。

const { PrismaClient } = require('@prisma/client')

const prisma = new PrismaClient()

❸ 作成するデータベースのモデルを指定

今回のデータベースには、「NextAuth.js」が基本としているモデルをそのまま使用しています。

// =====================================
// 3_作成するモデルを指定
// =====================================

// Accountモデル
model Account {
    ...
}

// Sessionモデル
model Session {
    ...
}

// Userモデル
model User {
    ...
}

[おまけ] MySQLの接続先URLの書き方

参照:Prisma 公式ドキュメント
// 基本の書き方
mysql://[USER]:[PASSWORD]@[HOST]:[PORT]/[DATABASE]

// 例
mysql://root:mypw@127.0.0.1:8889/project_databese
USERデータベースのユーザー名。
PASSWORDデータベースのパスワード。
HOSTホスト。
PORTポート。
DATABASEデータベースの名前。

[おまけ] NextAuth.jsで使用する基本モデル

NextAuth.jsでは基本となるデータベース構造を教えてくれています。

⑷ マイグレートを実行する

マイグレートを実行して、schema.prismaで指定したモデルのテーブルをデータベースに作成します。

$ npx prisma migrate dev

--nameを付けることでマイグレーションファイルに名前を付けることができます。

$ npx prisma migrate dev --name [マイグレーションファイル名]

$ npx prisma migrate dev --name first-migration  # 例
$ npx prisma migrate dev --name added_job_title  # 例

⑸ Pricma Clientを作成する

$ npx prisma generate

【Next.js】URLのクエリパラメータの取得方法。

関連:【Next.js】URLにクエリパラメータを付ける方法。

やりたいこと

https://example.com/post?post_id=100のURLの場合に、100を取得したい。

https://example.com/post?post_id=100

「getServerSideProps」内で取得する

export async function getServerSideProps({query}) {
    console.log(query.post_id);
}

// 100

「useRouter」で取得する

import { useRouter } from 'next/router'

...

const router = useRouter();
const post_id = router.query.post_id;
console.log(post_id);

...

// 100

「router.query」が空(undefined)になる場合

useRouter()で取得したrouter.queryが空(undefined)になってしまう場合があるようです。

対処法は、useEffect()とrouter.isReadyを組み合わせることで、パラメータが取得できたタイミングで処理を進められるようにできます。

import { useRouter } from 'next/router'

...

const router = useRouter();
const query = router.query;

useEffect(() => {
    if(router.isReady) {
        console.log(query.post_id);
    };
},[query, router]);

...

isReady: boolean – Whether the router fields are updated client-side and ready for use. Should only be used inside of useEffect methods and not for conditionally rendering on the server. See related docs for use case with automatically statically optimized pages

参照:next/router | Next.js

「getStaticProps」内では取得できない

export async function getStaticProps({params}) {
    console.log(query.post_id);
}

// undefined

【Next.js】URLにクエリパラメータを付ける方法。

関連:【Next.js】クエリパラメータの取得方法。

作りたいもの

こういうクエリパラメータを含むURLに飛べるリンクを作りたい。

https://example.com/posts?title=砂糖

⑴ Linkにクエリパラメータを指定する

import Link from "next/link";

...

<Link href={{ pathname: "/posts", query: {title: "砂糖"} }}>
    <a>タイトルに"砂糖"を含む投稿を見る</a>
</Link>

...

⑵「useRouter」を使う

import { useRouter } from 'next/router'

export default function Top() {
    const router = useRouter();
    
    // aタグがクリックされるとリダイレクト
    const handleClick = (keyword) => {
        router.push({
            pathname: "posts",
            query: { title: keyword },
        });
    };

    return(
        <div>
            <a onClick={() => handleClick('砂糖')}>タイトルに"砂糖"を含む投稿を見る</a>
            <a onClick={() => handleClick('塩')}>タイトルに"塩"を含む投稿を見る</a>
        </div>
    )
};

クエリパラメータを複数設定したい場合

Link」の場合も「router.push」の場合も、queryの中にパラメータを追加すると付与されます。

パラメータ一つの場合

query: {
    title: "砂糖"
} 

// https://example.com/posts?title=砂糖

パラメータ複数の場合

query: { 
    title: "砂糖",
    sort: "asc",
    ...,
},

// https://example.com/posts?title=砂糖&sort=asc

NextAuth.jsのオプションまとめ。

NextAuth.jsを利用していて、セッションの有効期限を変更したりカスタマイズしたくなりました。

NextAuth.jsのオプション設定でどんなことができるかまとめてみました。

NextAuth.jsの基本コード

import NextAuth from "next-auth"

export default NextAuth({
    ...

})

NextAuth.jsのオプション早見表

オプション名内容デフォルト値必須?
providersプロバイダの指定
(ログインに使用できるSNSサービスの種類を指定)
[]Yes
secret・Cookieの署名/暗号化などに使う設定string(開発)
No(本番)
Yes
(本番)
session・セッションに関する設定objNo
jwt???objNo
pages???{}No
callbacks・signIn, signOutなどアクションが起きた時に実行される処理のカスタマイズ設定objNo
events???objNo
adapter・外部DBやバックエンドシステムに接続するための設定
(ユーザー情報等をDBに保存したい場合など)
noneNo
debug???falseNo
logger???consoleNo
theme???objNo

providers

ユーザー登録(サインイン)やログインに使用できるプロバイダの設定

Google, Facebook, Twitter, GitHub, Emailなどなど。

export default NextAuth({
    ...,
    providers: [
        ...,
    ],
});

【関連記事】 NextAuth.jsで使える主要なプロバイダ一覧まとめ。

secret

「トークンのハッシュ化」や「Cookieの署名/暗号化」、「暗号化キーの生成」のために必要な設定。

本番環境の場合、「⑴ “secret“を記載」または「⑵ 環境変数に”NEXTAUTH_SECRET”を設定」のどちらかをしないとエラーになります。

方法⑴ “secret”を記載する

export default NextAuth({
    ...,
    secret: 'secret',
});

方法⑵ 環境変数に”NEXTAUTH_SECRET”を設定

下記コマンドで乱数を生成します。

$ openssl rand -base64 32

生成された乱数を環境変数に追加します。

NEXTAUTH_SECRET=[生成した乱数]

session

セッションに関する設定。

strategyセッション情報の保存方法(「JWT」や「データベース」など)
デフォルト値は“jwt”
「adapter」の指定されている場合は、デフォルトが“database”になる。
maxAgeセッションの有効期限。「秒」単位。
updateAgeセッション延長のためのデータベース更新頻度。「秒」単位。

セッションの有効期限は「どのくらいの期間、ログインしたままの状態が保たれるか」。

export default NextAuth({
    ...,
    session: {
        strategy: "database",
        maxAge: 30 * 24 * 60 * 60,  // 30 days
        updateAge: 24 * 60 * 60,  // 24 hours
    }
});

jwt

今後追記する…かも。

pages

今後追記する…かも。

callbacks

今後追記する…かも。

events

今後追記する…かも。

adapter

外部DBやバックエンドシステムに接続するための設定。UserデータやSessionデータなどをDBに保存したい場合などに必要な設定です。

例えば、ユーザー情報等を「Prisma」を使ってDBに保存したい場合など。

// 例:Prisma
import NextAuth from "next-auth"
import { PrismaAdapter } from "@next-auth/prisma-adapter"
import { PrismaClient } from "@prisma/client"

const prisma = new PrismaClient()

export default NextAuth({
    adapter: PrismaAdapter(prisma),
})

debug

今後追記する…かも。

logger

今後追記する…かも。

theme

今後追記する…かも。

まとめ

ユーザーのログインした状態を保持する期間を「session」で指定できることがわかって嬉しい。

NextAuth.jsで使える主要なプロバイダ一覧まとめ。

NextAuth.jsで、よく使われそうな主要なプロバイダをまとめました。

これでいろいろなSNSやWEBサービスのアカウントでユーザー登録できるようになります。

NextAuth.js

プロバイダを指定で編集するファイル

/pages/api/auth/[…nextauth].js のprovidersの中に記載していきます。

import NextAuth from "next-auth"

export default NextAuth({
    providers: [
        // ここにプロバイダを追加していきます。
        ...,
    ],
})

主要なプロバイダ一覧

プロバイダ名公式ドキュメントNextAuthページ
Applehttps://developer.apple.com/sign-in-with-apple/get-started/https://next-auth.js.org/providers/apple
Discordhttps://discord.com/developers/docs/topics/oauth2https://next-auth.js.org/providers/discord
Facebookhttps://developers.facebook.com/docs/facebook-login/manually-build-a-login-flow/https://next-auth.js.org/providers/facebook
GitHubhttps://developer.github.com/apps/building-oauth-apps/authorizing-oauth-appshttps://next-auth.js.org/providers/github
Googlehttps://developers.google.com/identity/protocols/oauth2https://next-auth.js.org/providers/google
Instagramhttps://developers.facebook.com/docs/instagram-basic-display-api/getting-startedhttps://next-auth.js.org/providers/instagram
LINEhttps://developers.line.biz/en/docs/line-login/integrate-line-login/https://next-auth.js.org/providers/line
Twitchhttps://dev.twitch.tv/docs/authenticationhttps://next-auth.js.org/providers/twitch
Twitterhttps://developer.twitter.com/https://next-auth.js.org/providers/twitter

Apple

プロバイダの公式ドキュメントhttps://developer.apple.com/sign-in-with-apple/get-started/
NextAuth.jsの詳細ページhttps://next-auth.js.org/providers/apple
import AppleProvider from "next-auth/providers/apple";

...
providers: [
    AppleProvider({
        clientId: process.env.APPLE_ID,
        clientSecret: process.env.APPLE_SECRET
    }),
    ...,
],
...

Discord

プロバイダの公式ドキュメントhttps://discord.com/developers/docs/topics/oauth2
NextAuth.jsの詳細ページhttps://next-auth.js.org/providers/discord
import DiscordProvider from "next-auth/providers/discord";

...
providers: [
    DiscordProvider({
        clientId: process.env.DISCORD_CLIENT_ID,
        clientSecret: process.env.DISCORD_CLIENT_SECRET
    }),
],
...

Facebook

プロバイダの公式ドキュメントhttps://developers.facebook.com/docs/facebook-login/manually-build-a-login-flow/
NextAuth.jsの詳細ページhttps://next-auth.js.org/providers/facebook
import FacebookProvider from "next-auth/providers/facebook";

...
providers: [
    FacebookProvider({
        clientId: process.env.FACEBOOK_CLIENT_ID,
        clientSecret: process.env.FACEBOOK_CLIENT_SECRET
    }),
],
...

GitHub

プロバイダの公式ドキュメントhttps://developer.github.com/apps/building-oauth-apps/authorizing-oauth-apps
NextAuth.jsの詳細ページhttps://next-auth.js.org/providers/github
import GitHubProvider from "next-auth/providers/github";

...
providers: [
    GitHubProvider({
        clientId: process.env.GITHUB_CLIENT_ID,
        clientSecret: process.env.GITHUB_CLIENT_SECRET
    }),
],
...

Google

プロバイダの公式ドキュメントhttps://developers.google.com/identity/protocols/oauth2
NextAuth.jsの詳細ページhttps://next-auth.js.org/providers/google
import GoogleProvider from "next-auth/providers/google";

...
providers: [
    GoogleProvider({
        clientId: process.env.GOOGLE_CLIENT_ID,
        clientSecret: process.env.GOOGLE_CLIENT_SECRET
    }),
],
...

Instagram

プロバイダの公式ドキュメントhttps://developers.facebook.com/docs/instagram-basic-display-api/getting-started
NextAuth.jsの詳細ページhttps://next-auth.js.org/providers/instagram
import InstagramProvider from "next-auth/providers/instagram";

...
providers: [
    InstagramProvider({
        clientId: process.env.INSTAGRAM_CLIENT_ID,
        clientSecret: process.env.INSTAGRAM_CLIENT_SECRET
    }),
],
...

Instagramでサインインを実装する場合には下記の記載が必要になります。

import { signIn } from "next-auth/react"

...
<button onClick={() => signIn("instagram")}>  // signInの中に"instagram"を記載
    Sign in
</button>

LINE

プロバイダの公式ドキュメントhttps://developers.line.biz/en/docs/line-login/integrate-line-login/
NextAuth.jsの詳細ページhttps://next-auth.js.org/providers/line
import LineProvider from "next-auth/providers/line";

...
providers: [
    LineProvider({
        clientId: process.env.LINE_CLIENT_ID,
        clientSecret: process.env.LINE_CLIENT_SECRET
    }),
],
...

Twitch

プロバイダの公式ドキュメントhttps://dev.twitch.tv/docs/authentication
NextAuth.jsの詳細ページhttps://next-auth.js.org/providers/twitch
import TwitchProvider from "next-auth/providers/twitch";

...
providers: [
    TwitchProvider({
        clientId: process.env.TWITCH_CLIENT_ID,
        clientSecret: process.env.TWITCH_CLIENT_SECRET
    }),
],
...

Twitter

プロバイダの公式ドキュメントhttps://developer.twitter.com/
NextAuth.jsの詳細ページhttps://next-auth.js.org/providers/twitter
import NextAuth from "next-auth"
import TwitterProvider from "next-auth/providers/twitter";

export default NextAuth({
    providers: [
        TwitterProvider({
            clientId: process.env.TWITTER_CLIENT_ID,
            clientSecret: process.env.TWITTER_CLIENT_SECRET
        }),
        ...,
    ],
})

その他

42 School, Amazon Cognito, Apple, Atlassian, Auth0, Authentik, Azure Active Directory, Azure Active Directory B2C, Battle.net, Box, BoxyHQ SAML, Bungie, Coinbase, Discord, Dropbox, EVE Online, Facebook, FACEIT, Foursquare, Freshbooks, FusionAuth, GitHub, GitLab, Google, IdentityServer4, Instagram, Kakao, Keycloak, LINE, LinkedIn, Mail.ru, Mailchimp, Medium, Naver, Netlify, Okta, OneLogin, Osso, Osu!, Patreon, Pipedrive, Reddit, Salesforce, Slack, Spotify, Strava, Trakt, Twitch, Twitter, United Effects, VK, WordPress.com, WorkOS, Yandex, Zoho, Zoom

出典:OAuth | NextAuth.js

【Next.js】Googleタグマネージャを設置する。

いつも「Googleアナリティクスのタグ設置」や「特定リンクのクリック計測」などを、Googleタグマネージャを使っています。

なのでNext.jsでもGoogleタグマネージャを使いたい。そこで今回はタグマネージャの設置方法をメモを調べてまとめておきます。

【方法1】「react-gtm-module」を使う

パッケージをインストールする

$ npm install react-gtm-module --save

_app.jsを編集する

import '../styles/globals.css'
import React, {useEffect} from "react";
import {SessionProvider} from 'next-auth/react';
import TagManager from 'react-gtm-module';

function MyApp({ Component, pageProps } }) {
    // Google Tag Manager設定
    useEffect(() => {
        TagManager.initialize({ gtmId: [YOUR_GOOGLE_TAG_MANAGER_ID] });
    }, []);

    return <Component {...pageProps}/>
};

export default MyApp;

【方法2】「_document.js」に直接コードを追加する

pages下に「_document.js」を作成する

まずpagesディレクトリ内に_document.jsを作成して、下記のコードを記載します。

import Document, {Html, Head, Main, NextScript} from 'next/document';
import React from "react";

export default class MyDocument extends Document {
    render() {
        return (
            <Html>
                <Head>
                    {/* 1: Google Tag Manager ---------------------------- */}
                    <script dangerouslySetInnerHTML={{
                        __html: `(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start': new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0], j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src= 'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);})(window,document,'script','dataLayer','[GTM_ID]');`,
                    }}/>
                    {/* -------------------------------------------------- */}
                </Head>
                <body>
                    {/* 2: Google Tag Manager ---------------------------- */}
                    <noscript dangerouslySetInnerHTML={{
                        __html: `<iframe src="https://www.googletagmanager.com/ns.html?id=[GTM_ID]" height="0" width="0" style="display:none;visibility:hidden" />`,
                    }}/>
                    {/* -------------------------------------------------- */}
                    <Main/>
                    <NextScript/>
                </body>
            </Html>
        );
    }
};
このコードが表示されるように設定

「コンテナID」を書き換える

あとはコードの[GTM_ID]の部分(2ヶ所)を、タグマネージャの「コンテナID」に書き換えるだけで設置の作業は完了です。

まとめ

Googleタグマネージャを無事設置することができました。

【Next.js】robots.txtを作る。

Googleなどの検索エンジンのクローラに対して、サイトの情報(サイトマップの場所など)を伝えるための「robots.txt」を作る方法をメモしていきます。

robots.txtを作成する

publicフォルダ内に「robots.txt」ファイルを作成します。

robots.txtの書き方

User-agent: *
Allow: /

Sitemap: https://[ドメイン]/sitemap.xml