タグ: react

  • コラム 文字の無いボタンには aria-label をつけよう

    コラム 文字の無いボタンには aria-label をつけよう

    🐏 この記事はコラムです

    ユーザー補助の観点から、文字の無いボタンは、スクリーンリーダーを使用しているユーザーにとっては「ボタン」として読み上げられてしまい、どのような意味なのかわかりません。

    Google PageSpeed Insights では上記画像のような警告が出てしまいます。

    改善方法として button タグに以下のように aria-label を仕込みましょう。

    <button aria-label="ホームーページへ移動">
      <Button
        variant="plain"
        onClick={() => handleNavigate('/')}
        aria-label="ホームページに移動"
      >

  • JOY UI で全体のスタイルを変更する方法 TS 対応

    JOY UI で全体のスタイルを変更する方法 TS 対応

    この記事は?

    Joy UI を使ってUIを構築する際、フォントやPrimary Color などの共通のスタイルを変更する方法についてです。
    個別に変更するばは sx プロップスを使用すればいいのですが、全体の変更する場合は extendTheme を使います。
    以下解説です。

    よしなに。

    環境

    • React TS
    • Joy UI v5.0.0-beta.49
    • 2025.01.20 時点

    やり方

    以下のように thmes ディレクトリなどを作成し、その下にtheme.ts ファイルを作成します。

    中身は例えば以下のようにしてみましょう。
    extendTheme を使うのがポイントです。

    // src/themes/theme.ts
    import { extendTheme } from '@mui/joy/styles';
    
    const theme = extendTheme({
      colorSchemes: {
        light: {
          palette: {
            primary: {
              50: '#e3f2fd',
              100: '#bbdefb',
              200: '#90caf9',
              300: '#64b5f6',
              400: '#42a5f5',
              500: '#2196f3',
              600: '#1e88e5',
              700: '#1976d2',
              800: '#1565c0',
              900: '#0d47a1',
            },
          },
        },
      },
      fontFamily: {
        display: 'Roboto, sans-serif',
        body: 'Arial, sans-serif',
      },
    });
    
    export default theme;

    続いてこの関数を App.tsx で読み込みます。

    CssVarsProvider で全てを囲ってあげます。そして、themeに先ほど作成したtheme.tsを渡してあげればスタイルが下層の全てのコンポーネントに適応されます。

    import React from 'react';
    import { BrowserRouter as Router, Route, Routes } from 'react-router-dom';
    import './styles/App.css';
    import { RecoilRoot } from 'recoil';
    
    // theme
    import { CssVarsProvider } from '@mui/joy';
    import theme from './themes/theme';
    
    // component
    // 省略
    
    function App() {
      return (
        <RecoilRoot>
          <CssVarsProvider theme={theme}>
          <Router>
            <Header />
            <Analytics />
            <Routes>
              <Route path="/" element={<Top />} />
            </Routes>
          </Router>
          </CssVarsProvider>
        </RecoilRoot>
      );
    }
    
    export default App;

    たったこれだけで、プロジェクト全体に変更をかけられるようになりました!
    お疲れ様です!!

    参考

    ↓ 公式ドキュメント様

    https://mui.com/joy-ui/customization/approaches

    おまけ

    mac, windows, 他OSでフォントを切り替えられるようにしてみました。

    // 
    //  このファイルは、JoyUI のテーマを定義するファイルです。
    //  created date: 2025.01.20
    //  created by: coiai
    // 
    
    import { extendTheme } from '@mui/joy/styles';
    
    // OSごとのフォント設定
    const getSerifFont = () => {
      const platform = navigator.platform.toLowerCase();
    
      if (platform.includes('win')) {
        return 'Yu Mincho, serif'; // Windows の場合は遊明朝
      } else if (platform.includes('mac')) {
        return 'Hiragino Mincho Pro, serif'; // Mac の場合はヒラギノ明朝
      } else {
        return 'serif'; // その他のOSはデフォルトのセリフ体
      }
    };
    
    const theme = extendTheme({
      colorSchemes: {
        light: {
          palette: {
            primary: {
              50: '#e3f2fd',
              100: '#bbdefb',
              200: '#90caf9',
              300: '#64b5f6',
              400: '#42a5f5',
              500: '#2196f3',
              600: '#1e88e5',
              700: '#1976d2',
              800: '#1565c0',
              900: '#0d47a1',
            },
          },
        },
      },
      fontFamily: {
        display: getSerifFont(), // 見出し用フォント
        body: getSerifFont(),    // 本文用フォント
      },
    });
    
    export default theme;
    明朝体に変更した画面
  • React で構築した SPA のSEO対策一覧

    今回WordPress Rest API とReactを用いてサイトを構築しました。
    その際に行ったSEO対策についてメモしておきます。

    URLに直接アクセスした時の対応

    React は基本的にSPAなので、サーバーが全てのリクエストをReact アプリのエントリーポイントにリダイレクトするように設定する必要があります。

    .htaccess に以下の記述をします。

    <IfModule mod_rewrite.c>
      RewriteEngine On
      RewriteCond %{REQUEST_FILENAME} !-f
      RewriteCond %{REQUEST_FILENAME} !-d
      RewriteRule ^ /index.html [L]
    </IfModule>

    GA4 の設定

    パッケージを用いる場合は react-ga4 を使ってみましょう。

    私は Analytics.ts というファイルを作り、App.tsx に読み込ませました。

    import { useEffect } from 'react';
    import { useLocation } from 'react-router-dom';
    import ReactGA from 'react-ga4';
    
    const TRACKING_ID = 'G-yourcode'; // GoogleアナリティクスのトラッキングIDを設定
    
    ReactGA.initialize(TRACKING_ID);
    
    function Analytics() {
      const location = useLocation();
    
      useEffect(() => {
        // ページが変更されるたびにトラッキング情報を送信
        ReactGA.send({ hitType: 'pageview', page: location.pathname });
      }, [location]);
    
      return null; // UIに表示するものはない
    }
    
    export default Analytics;
    function App() {
      return (
        <RecoilRoot>
          <Router>
            <Header />
            <Analytics />
            <Routes>
              <Route path="/" element={<top />} />
            </Routes>
          </Router>
        </RecoilRoot>
      );
    }

    メタタグとOGタグの設定

    React-helmet だと現在の環境ではエラーの原因になります。react-helmet-asyncを使いましょう。

    React で動的にメタ情報を設定するには react-helmet-asyncや@tankstack/react-head を使います。

    以下はReact helmet-async を使った例です。

    import React from 'react';
    import ReactDOM from 'react-dom/client'
    import './styles/index.css';
    import App from './App';
    import reportWebVitals from './reportWebVitals';
    
    // helmet
    import { HelmetProvider } from 'react-helmet-async';
    
    const root = ReactDOM.createRoot(
      document.getElementById('root') as HTMLElement
    );
    root.render(
      <React.StrictMode>
        <HelmetProvider>
          <App />
        </HelmetProvider>
      </React.StrictMode>
    );
    
    // 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();
    
    import { Helmet } from "react-helmet-async";
    
    function MyPage() {
      return (
        <div>
          <Helmet>
            <title>ページタイトル</title>
            <meta name="description" content="ページの説明文" />
            <meta property="og:title" content="ページタイトル" />
            <meta property="og:description" content="ページの説明文" />
            <meta property="og:image" content="画像URL" />
            <meta name="robots" content="index, follow" />
          </Helmet>
          <h1>コンテンツ</h1>
        </div>
      );
    }

    https://www.npmjs.com/package/react-helmet-async ←参考ドキュメント

    Sitemap, robots.txt の設定

    react-router-sitemap を使用して自動生成(node.js を使っている場合)
    または手動で追加します。

    手順を別記事にしました。

    https://coiai.boy.jp/3784/

    構造化データのマークアップ

    JSON-LDを使う。

    <script type="application/ld+json">
    {
      "@context": "https://schema.org",
      "@type": "WebPage",
      "name": "ページタイトル",
      "description": "ページの説明文",
      "url": "https://example.com"
    }
    </script>

    SSR サーバーサイドレンダリングの導入

    Next.js などのフレームワークを使用して、SSRを実装する。

    動的レンダリング

    Rendertron, Prerender.io を使う。

    ↓ Google 検索セントラル公式のRedertron についての解説https://developers.google.com/search/blog/2019/01/dynamic-rendering-with-rendertron?hl=ja

    Rendertron の軽い理解

    Rendertron は、検索エンジンが JavaScript アプリケーションを正しくインデックスできるよう、静的 HTML を生成して提供するツールです。

    1. ユーザーリクエスト

    通常のユーザーリクエストは JavaScript アプリ(React アプリ)をそのまま提供します。

    2. クローラーリクエスト

    Googlebot や他のクローラーからのリクエストを検知し、Rendertron を使用して静的 HTML を生成して提供します。

    SSG 静的サイト生成

    コンテンツが更新されない場合は各ページのHTMLを事前に生成することができる。

    Gatsby などの生成ツールを使うのが一つの手です。

    もしくはreact 単体で動作させる場合は react-snap を使うという手があります。

  • React 単体のプロジェクトに sitemap を導入してSEOスコアを向上させる

    React単体でsitemap を導入する方法について解説します。

    通常はバックエンドに他のフレームワークを使っている場合は、そちらでやるのが一般的だと思いますが、React をビルドしてシンプルに運用している場合は、自分で作るしかありません。

    やり方 手動

    public ディレクトリの下に sitemap.xml を作成します。

    そこにたとえば以下のように記述します。

    <?xml version="1.0" encoding="UTF-8"?>
    <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
      <url>
        <loc>https://yourdomain.com/</loc>
        <priority>1.0</priority>
      </url>
      <url>
        <loc>https://yourdomain.com/company</loc>
        <priority>0.8</priority>
      </url>
      <url>
        <loc>https://yourdomain.com/office-treatment</loc>
        <priority>0.8</priority>
      </url>
      <!-- 他のルートをここに追加 -->
    </urlset>

    続いて robots.txt に以下のように記述します。

    Sitemap: https://your-page.com/sitemap.xml

    your-page のところはあなたのドメインに置き換えましょう。