LoginSignup
8
1

More than 1 year has passed since last update.

【React】head の title をコンポーネントごとに変更する

Last updated at Posted at 2022-11-16

はじめに

タブのタイトル名やお気に入りに入れた際のタイトルは、head タグ内の title タグの値が反映されています。

<head>
  <title>My test page</title>
</head>

今回はこの title を React コンポーネント内で変更する方法をまとめて行きたいと思います。
結論としては react-helmet-async というライブラリを使うことで解決します。

対象読者

  • React の基本的な使い方がわかるエンジニア
  • react-helmet-async の使い方が知りたい人

また、最終的なコードは下記リポジトリに記載しています。

環境構築

今回は vite 使ってみたかったので

こちらをみながら環境構築をしました。
create-react-app よりだいぶ早くできてかなりいい感じですね。

version

$ node -v
v16.17.1
$ yarn -v
1.22.19
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-helmet-async": "^1.3.0",
"react-router-dom": "^6.4.3",
"@types/react": "^18.0.17",
"@types/react-dom": "^18.0.6",
"@vitejs/plugin-react": "^2.1.0",
"typescript": "^4.6.4",
"vite": "^3.1.0"

初期設定

必要なライブラリをインストールします

$ yarn add react-helmet-async
$ yarn add react-router-dom

routing 設定

react-helmet-async を使用する前にまず、
React Router を用いて link を押下すると別コンポーネントに遷移できるようにします。

touch src/page1.tsx
page1.tsx
export const Page1 = () => {
  return (
    <div>
      <h1>Page1</h1>
      <nav>
        <ul>
          <li>
            <a href={`/`}>home</a>
          </li>
          <li>
            <a href={`page1`}>page1</a>
          </li>
        </ul>
      </nav>
    </div>
  );
};

src 配下に page1.tsx を作成し、上記コードを記載します。

app.tsx
import './App.css'

function App() {
  return (
    <div>
      <h1>home</h1>
      <nav>
          <ul>
            <li>
              <a href={`/`}>home</a>
            </li>
            <li>
              <a href={`page1`}>page1</a>
            </li>
          </ul>
        </nav>
    </div>
  )
}

export default App

app.tsx を修正しスッキリさせ、リンクを配置します。この時点ではまだ遷移しても page1 は表示されません。

React Router を使って、遷移した path によって表示する component を切り替えられるようにします。

main.tsx
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App'
import './index.css'
import { Page1 } from './page1';
import {  createBrowserRouter, RouterProvider } from "react-router-dom";

const router = createBrowserRouter([
  {
    path: "/",
    element: <App />,
  },
  {
    path: "/page1",
    element: <Page1 />,
  },
]);

ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
  <React.StrictMode>
    <RouterProvider router={router} />
  </React.StrictMode>
)

createBrowserRouter の引数に path とそれによって表示される component を指定し、
という component の props に指定することでページ遷移の行き来が可能になります。

head の title をコンポーネントごとに変更

ここからが本題です。

main.tsx
<React.StrictMode>
  <HelmetProvider>
    <RouterProvider router={router} />
  </HelmetProvider>
</React.StrictMode>

main component を HelmetProvider でラップします。

Helmet component を追加

const componentName = "Home";

コンポーネントごとに表示する文字列を変数として定義しておきます。

<Helmet>
  <title>{componentName}</title>
</Helmet>

こちらのコンポーネントを各ページに追加します。

最終的なコード

import './App.css'
import { Helmet } from 'react-helmet-async';


function App() {
  const componentName = "Home";
  return (
    <div>
      <Helmet>
        <title>{componentName}</title>
      </Helmet>
      <h1>Home</h1>
      <nav>
          <ul>
            <li>
              <a href={`/`}>Home</a>
            </li>
            <li>
              <a href={`page1`}>Page1</a>
            </li>
          </ul>
        </nav>
    </div>
  )
}

export default App
import { Helmet } from "react-helmet-async";

export const Page1 = () => {
  const componentName = "Page1";
  return (
    <div>
      <Helmet>
        <title>{componentName}</title>
      </Helmet>
      <h1>Page1</h1>
      <nav>
        <ul>
          <li>
            <a href={`/`}>Home</a>
          </li>
          <li>
            <a href={`page1`}>Page1</a>
          </li>
        </ul>
      </nav>
    </div>
  );
};

このようにするとページ遷移するとそのページのタイトルを component 名にすることができます。

終わりに

この技術を活用すれば、例えば詳細画面のタイトルを選択したオブジェクト名にするなどいったことができるようになると思います。

コンポーネントを追加するだけでサクッとできるので便利ですね。

参考文献

8
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
1