Reactの続きです。前回は以前作成したメタ言語スターターキットの内容を移植してHTML部分をコンポーネント化しました。今回はheadタグを動的に打ち替えたく、react-helmetを使ってみます。それではいきましょう!
【目次】
- 前回のおさらい
- 前回はheadタグにベタ書き
- そうだ、react-helmetでheadタグ 打ち替えよう
- App.tsxを作成
- react-helmetのインストール
- Helmetコンポーネントを設定
- 変数のテキストでtitleとdescriptionを打ち替え
- 最後に
※参考:前回記事
【React】HTMLコンポーネント化(Reactとメタ言語の比較-1) - クモのようにコツコツと
※参考:Reactを習得するためにやったことまとめ
qiita.com
前回のおさらい
以前作成したメタ言語スターターキットのコンパイル語のコードを移植。
React + TypeScript + CSS in JSの構造で作り替えて比較したい。まずはHTML部分をReactのコンポーネント化した。
※参考:【React】HTMLコンポーネント化(Reactとメタ言語の比較-1) - クモのようにコツコツと
前回はheadタグにベタ書き
前回、「src」フォルダの「index.tsx」でHTMLをコンポーネント化した
ReactDOM.render( <React.StrictMode> <Header /> <Main /> <Footer /> </React.StrictMode>, document.getElementById('root') );
Header
、Main
、Footer
コンポーネントを読み込み#root
にレンダリングする。
#root
は「public」フォルダの「index.html」にある。
<body> <noscript>You need to enable JavaScript to run this app.</noscript> <div id="root"></div> <!-- 中略 --> </body>
headタグの中にはtitle
やdescription
のテキストがベタ書きになっている。
<head> <!-- 中略 --> <meta name="description" content="以前作ったメタ言語スターターキットの内容をReact環境で再現してみる" /> <!-- 中略 --> <title>Reactとメタ言語の比較</title> </head>
メタ言語スターターキットのEJSの時はheadタグの中身も外部から読み込んだテキストで打ち替えていた。
<meta charset="UTF-8"> <title><%= header.title %></title> <meta name="description" content="<%= header.text %>"> <link rel="stylesheet" href="css/style.css"> <script src="js/script.js"></script>
※参考:【メタ言語】フロントエンド開発スターターキットを作った(EJS、Sass(SCSS)、TypeScript) - クモのようにコツコツと
こういうことをReactでもできないものか。Reactはbodyタグ内のHTMLタグにJSXをレンダリングするからなー。
そうだ、react-helmetでheadタグ 打ち替えよう
調べるとReactでheadタグを打ち変える「react-helmet」というパッケージがあることを知った。
その他、参考記事
※参考:Gatsby.jsにreact-helmetを導入してhead要素(メタタグ)をカスタマイズする | webOpixel
※参考:metaタグを変えるためにreact-helmetを導入してみたけれど結局ES2015で実装した話 - LCL Engineers' Blog
※参考:SSR無しでReactアプリをOGPとかに対応させる (自力prerendering編) - Qiita
よし、いっちょやってみっか〜(悟空の声で)
App.tsxを作成
headがある「index.html」自体ではReactは動かせない。ここにはJSXをレンダリングする起点となる#root
があるだけだ。
こちらの記事は自分と同じく 「Create React App」でreact-helmetを導入している事例がある!
※参考:SSR無しでReactアプリをOGPとかに対応させる (自力prerendering編) - Qiita
「Create React App」の「App.js」でhelmetを設定し、「index.html」のheadタグを打ち替えできているようだった。
前回、「App.tsx」をいったん削除していたが再度作成する。
「index.tsx」にはHeader
、Main
、Footer
コンポーネントをインポートしていたが、App
コンポーネントだけをインポートする。
import React from 'react'; import ReactDOM from 'react-dom'; import './index.css'; import App from './App'; import reportWebVitals from './reportWebVitals'; ReactDOM.render( <React.StrictMode> <App /> </React.StrictMode>, document.getElementById('root') ); // If you want to start measuring performance in your app, pass a function // to log results (for example: reportWebVitals(console.log)) // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals reportWebVitals();
「index.tsx」でインポートしていたHeader
、Main
、Footer
コンポーネントはこの「App.tsx」で読み込むことにする。
import React from 'react'; import Header from './Header'; import Main from './Main'; import Footer from './Footer'; function App() { return ( <div className="App"> <Header /> <Main /> <Footer /> </div> ); } export default App;
よし、ここにreact-helmetを導入するどー♪
react-helmetのインストール
react-helmetをインストールする。こちらのコマンド
npm i react-helmet
TypeScript環境なので以前インストールした「styled-components」と同様、今回も@typesも入れないとエラーになった。
※参考:【React】React + TypeScript + CSS in JSの開発環境を作る(Gitエラー対処も) - クモのようにコツコツと
こちらのコマンド
npm i @types/react-helmet --save-dev
@types
のコマンドはこちらで調べることができる。
※参考:TypeScript: Search for typed packages
package.jsonを確認。react-helmet
はdependencies
に
"dependencies": { // 中略 "react-helmet": "^6.1.0", // 中略 },
@types/react-helmet
はdevDependencies
に追加された
"devDependencies": { "@types/react-helmet": "^6.1.0" }
Helmetコンポーネントを設定
公式ドキュメントを参考にHelmet
コンポーネントを設定する。
このようにHelmet
コンポーネントの中にベタ書き。
function App() { return ( <div className="App"> <Helmet> <meta charSet="utf-8" /> <title>My Title</title> <link rel="canonical" href="http://mysite.com/example" /> </Helmet> <Header /> <Main /> <Footer /> </div> ); }
アプリを起動すると
$ npm start
Dev-toolsで確認すると、おお!titleが「My Title」に変わっている!
変数のテキストでtitleとdescriptionを打ち替え
headタグをReactで打ち替えられたのは嬉しいが、このままだとテキストがベタ書きなのは変わらない。やはり動的に打ち替えたい。
こちらの記事のようにHelmet
コンポーネントの中に属性として設定してみよう。
※参考:Gatsby.jsにreact-helmetを導入してhead要素(メタタグ)をカスタマイズする | webOpixel
まず、変数titleText
とdescriptionText
にテキストを設定
const titleText = 'Reactとメタ言語の比較'; const descriptionText = '以前作ったメタ言語スターターキットの内容をReact環境で再現してみる';
titleText
とdescriptionText
をHelmet
コンポーネントの属性に設定する。
function App() { return ( <div className="App"> <Helmet title={ titleText } meta={[ { name: 'description', content: descriptionText } ]} /> <Header /> <Main /> <Footer /> </div> ); }
属性の値部分は{}
で囲って、さらにmetaタグは複数設定できるので[]
で配列にする。
「index.html」のtitleタグは全然違うテキストにしてみた。
<head> <!-- 中略 --> <title>helmetで打ち替えテストだよ〜ん</title> </head>
なお、descriptionは上書きされず二重になったため、index.htmlの方はは消してみた。下記の記事と同じ挙動。
※参考:metaタグを変えるためにreact-helmetを導入してみたけれど結局ES2015で実装した話 - LCL Engineers' Blog
ブラウザを確認すると、おお、titleとdescriptionが打ち変わった!
Sorcesパネルを見るとtitleは「helmetで打ち替えテストだよ〜ん」のまま。
ソース(GitHub)※今回のコミットまで
※参考:GitHub - ryo-i/react-from-meta-lang at b5806001337be58355f4843de94666397ab52857
プレビュー(GitHub Pages)
※参考:Reactとメタ言語の比較
最後に
ということで、Reactでheadタグの中身を打ち変えることができました。これでページtitleとh1タグを共通テキストから読み込んで、メンテナンスをあげることができそうです。
今回は取り急ぎ変数のテキストを読み込んだけど、外部のJSONファイルから読み込む構成にしていきたいと思います。
また、headタグをReactで打ち替えられるということで、「react-router(ページのURLパスを変更)」と組み合わせて、SPA(シングルページアプリケーション)のページ遷移が表現することができそう♪
※参考:SSR無しでReactアプリをOGPとかに対応させる (自力prerendering編) - Qiita それではまた!
※参考:Reactを習得するためにやったことまとめ
qiita.com