はじめに
タブのタイトル名やお気に入りに入れた際のタイトルは、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
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 を作成し、上記コードを記載します。
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 を切り替えられるようにします。
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 をコンポーネントごとに変更
ここからが本題です。
<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 名にすることができます。
終わりに
この技術を活用すれば、例えば詳細画面のタイトルを選択したオブジェクト名にするなどいったことができるようになると思います。
コンポーネントを追加するだけでサクッとできるので便利ですね。
参考文献