TailWindCSSとNextJSを使用したアクセス可能なパンくずのナビゲーションの作成


BreadCrumbのナビゲーションは、多くのアプリケーションでは最近、ほとんどのダッシュボードに表示され始めている.今日、我々はアクセス可能で、TarwindCSSでスタイルを整えられたパンくずのナビゲーションを構築するつもりです.私たちはnextjsを使用するつもりですNextJS Router ) このチュートリアルではしかし、あなたは他のフレームワークのために同じステップに従うことができます、それは反応フレームワークでないかもしれません.ちょうど適切なルータロジックを見て、実装して、適切に構成要素をつくるようにしてください、スタイリングは同じままです.

🍞 を、何がパン粉ナビゲーションですか?
ナビゲーションバーには、このようなものがあったに違いない.


最初の例はVercel ダッシュボードと2番目のものはNetlify ダッシュボード.
ページがどのページにあるかを簡単に考え、簡単に戻ることができます(はい、それらのパン粉アイテムは通常リンクされます).
時々、これらのパンくずはリンクも関連したドロップダウンを持ちます.

より高度なユースケースであるため、今日はこれを構築することはできません.しかし、より大きなプロジェクトでは、ナビゲーションを容易にするために有用なものになります.

アプリケーションを初期化する
まず最初に、新しいnextjsアプリケーションを作成しましょう
npx create-next-app breadcrumb-example
# OR
yarn create next-app breadcrumb-example
さて、Boilerplateコードと既存のCSSの一部を削除しますglobal.css としてTailWindCSSを追加します.
クリーンアップpages/index.js このようになります-
import Head from "next/head";

export default function Home() {
  return (
    <div>
      <Head>
        <title>NextJS Breadcrumb Example</title>
        <meta
          name="description"
          content="A simple example application for a NextJS Breadcrumb tutorial"
        />
        <link rel="icon" href="/favicon.ico" />
      </Head>

      <main>
        <h1>Breadcrumb Navigation Example with NextJS</h1>
      </main>
    </div>
  );
}
また、削除Home.module.css の下にstyles ディレクトリ.

を追加する
我々は、単に次の事務所ガイドに従うことになるadding TailwindCSS to a NextJS application .
まずはTailWindCSS、Postcss、AutoPrefixerをインストールしましょう.
npm install -D tailwindcss postcss autoprefixer
# OR
yarn add -D tailwindcss postcss autoprefixer
また、次のコマンドを実行してtailwind.config.js and postcss.config.js ファイル
npx tailwindcss init -p
さて、tailwind.config.js 以下のファイルを指定します.
module.exports = {
  content: [
    "./pages/**/*.{js,ts,jsx,tsx}",
    "./components/**/*.{js,ts,jsx,tsx}",
  ],
  theme: {
    extend: {},
  },
  plugins: [],
}
さて、次のコードをglobals.css ファイル下にstyles ディレクトリ
@tailwind base;
@tailwind components;
@tailwind utilities;
この例では、私はダークモードのバージョンに行くつもりです、ちょうど私が取るスクリーンショットは目に簡単です.このために、私はこれを私に加えますglobals.css ファイル
@layer base {
  body {
    @apply bg-black text-white;
  }
}
私もいくつかのスタイルを追加するにはh1 我々が以前に加えたタグindex.js ファイル
<h1 className="mx-8 md:mx-16 lg:mx-32 mt-32 text-2xl md:text-3xl lg:text-4xl">
    Breadcrumb Navigation Example with NextJS
</h1>
これがウェブサイトのようです.


パンくずのナビゲーションの構築
楽しい部分のための時間は、パン粉のナビゲーションを構築しよう!
新しいディレクトリを作りましょうcomponents . これは、我々が我々を入れているところですBreadcrumb and BreadcrumbItem コンポーネント.
さあ、パン粉を作ってみよう.ファイルを作成するBreadcrumb.jsx 次のコードを追加します.
import { Children } from "react";
import { Fragment } from "react/cjs/react.production.min";

const Breadcrumb = ({ children }) => {
  const childrenArray = Children.toArray(children);

  console.log(childrenArray);

  const childrenWtihSeperator = childrenArray.map((child, index) => {
    if (index !== childrenArray.length - 1) {
      return (
        <Fragment key={index}>
          {child}
          <span>/</span>
        </Fragment>
      );
    }
    return child
  });

  return (
    <nav className="mx-8 md:mx-16 lg:mx-32 mt-8">
      <ol className="flex items-center space-x-4">{childrenWtihSeperator}</ol>
    </nav>
  );
};

export default Breadcrumb;
このコードを一歩一歩進めましょう.まず第一に、私たちはBreadcrumb . 私たちは子供たちです.これらの子には、ページへのリンクです.
次に、子プロセスを Children.toArray() function .
我々が記録するならばchildrenArray コンソールに変数を設定します.

ここでは、プロップ、コンポーネントの種類などのコンポーネントに関するすべてのメタデータが含まれていることがわかります.
次に、この配列を取り、その上にマップします.配列の最後の要素が、index 配列の長さを持つ要素です.最後の要素でない場合、React Fragment 子要素自体とセパレータ(/ この場合、それは最も一般的なものですが、同様にそれを変更することができます).配列の最後の要素であれば、要素を返します.
次に、パンクラムコンポーネントはnav 要素リストを持つ要素ol ). オーダーリストは、Flexboxspace-x-4 クラスは、1 rem すべての子要素の間(この場合のパン粉の項目).
最後に、後で使用するコンポーネントをエクスポートします.
さて、別のファイルを作成しましょうBreadcrumbItem.jsx 次のコードを追加します.
import Link from "next/link";

const BreadcrumbItem = ({ children, href, ...props }) => {
  return (
    <li {...props}>
      <Link href={href} passHref>
        <a>{children}</a>
      </Link>
    </li>
  );
};

export default BreadcrumbItem;
ここでは、私たちはBreadcrumbItemchildrenhref プロップまた、私たちに追加されます追加の小道具はli プロップ注意してくださいBreadcrumbItem リスト項目であり、したがって、それは我々が以前に作成した順序付けられたリストに収まりますBreadcrumb コンポーネント.
時間は、アプリケーションにパン粉を追加します.当分の間、次のコードを加えましょうindex.js ファイル下pages -
<Breadcrumb>
    <BreadcrumbItem href="/">Home</BreadcrumbItem>
    <BreadcrumbItem href="/">Home</BreadcrumbItem>
</Breadcrumb>
また、インポートを忘れないでください
import Breadcrumb from "../components/Breadcrumb";
import BreadcrumbItem from "../components/BreadcrumbItem";
これはホームページが今のように見えるものです.

たった今、私たちはホームページのパンデットをレンダリングし、ページ名をハードコーディングしています.しかし、これは我々がしなければならないことではありません、ルートがルータコンポーネントを使用して推論されるより良いアプローチを見てみましょう.

動的にパン粉項目を作成する
今までは、我々は手動でパン粉のアイテムをBreadcrumb コンポーネント.しかし、このアプローチは、より大きなアプリケーションに適していない.
私はいくつかの変更を行った_app.js ファイルを動的にパン粉アイテムを作成する
import { useRouter } from "next/router";
import { useEffect, useState } from "react";
import "../styles/globals.css";
import Breadcrumb from "../components/Breadcrumb";
import BreadcrumbItem from "../components/BreadcrumbItem";

function MyApp({ Component, pageProps }) {
  const router = useRouter();
  const [breadcrumbs, setBreadcrumbs] = useState();

  useEffect(() => {
    const pathWithoutQuery = router.asPath.split("?")[0];
    let pathArray = pathWithoutQuery.split("/");
    pathArray.shift();

    pathArray = pathArray.filter((path) => path !== "");

    const breadcrumbs = pathArray.map((path, index) => {
      const href = "/" + pathArray.slice(0, index + 1).join("/");
      return {
        href,
        label: path.charAt(0).toUpperCase() + path.slice(1),
      };
    });

    setBreadcrumbs(breadcrumbs);
  }, [router.asPath]);

  return (
    <>
      <Breadcrumb>
        <BreadcrumbItem href="/">Home</BreadcrumbItem>
        {breadcrumbs &&
          breadcrumbs.map((breadcrumb) => (
            <BreadcrumbItem key={breadcrumb.href} href={breadcrumb.href}>
              {breadcrumb.label}
            </BreadcrumbItem>
          ))}
      </Breadcrumb>
      <Component {...pageProps} />
    </>
  );
}

export default MyApp;
このコードを読みましょう.まず、nextjsルータをインポートします.the useEffect hook , the useState hook , the Breadcrumb コンポーネントとBreadcrumbItem コンポーネント.また、からのパン粉コンポーネントを削除することができますindex.js ファイル.
そして、内部MyApp コンポーネントは、ルータを初期化しており、パンくずを保存する状態を作成します.次に、我々はuseEffect ページが読み込まれるたびに発生するフックrouter.asPath 変更点
useEffect フック、まず、クエリパラメータをパスから削除しますrouter.asPath ). 次に、それをpathArray を呼び出し、 shift() 関数は、最初の要素(ホームルートです)を削除します.
次に、他の空白のパスを取得しないようにフィルタリングします.これは、NextJSルータがホームルート上にある場合、最後のインデックスで空白の要素を返すためです.
その後、我々map それを超えて新しい配列を生成するbreadcrumbs . The breadcrumbs array 1 iを含むオブジェクトの配列ですhref and label パン粉アイテムのために.
最後に、我々はそれを保存しますbreadcrumbs 我々がそれを外で使うことができるように、状態useEffect フック.
次に、JSXでは、Breadcrumb コンポーネントを追加BreadcrumbItem それへのホームルートのために.
それから、我々はbreadcrumbs arrayはNULLではなく、その上にマップされますBreadcrumbItem コンポーネント.
さて、それをテストするためにdashboardpages を追加し、index.js and [id].js .
次のコードを追加しますindex.js -
import Head from "next/head";

const Dashboard = () => {
  return (
    <div>
      <Head>
        <title>Dashboard | NextJS Breadcrumb Example</title>
        <meta
          name="description"
          content="A simple example application for a NextJS Breadcrumb tutorial"
        />
        <link rel="icon" href="/favicon.ico" />
      </Head>

      <main>
        <h1 className="mx-8 md:mx-16 lg:mx-32 mt-32 text-2xl md:text-3xl lg:text-4xl">
          Breadcrumb Navigation Example with NextJS - Dashboard Page
        </h1>
      </main>
    </div>
  );
};

export default Dashboard;
さて、次のコードを追加します[id].js -
import Head from "next/head";

const Project = () => {
  return (
    <div>
      <Head>
        <title>Dynamic Route | NextJS Breadcrumb Example</title>
        <meta
          name="description"
          content="A simple example application for a NextJS Breadcrumb tutorial"
        />
        <link rel="icon" href="/favicon.ico" />
      </Head>

      <main>
        <h1 className="mx-8 md:mx-16 lg:mx-32 mt-32 text-2xl md:text-3xl lg:text-4xl">
          Breadcrumb Navigation Example with NextJS - Dynamic Route Page
        </h1>
      </main>
    </div>
  );
};

export default Project;
さて、私たちは/dashboardimage.png
我々はパン粉が正常に動作し、リンクも動作することがわかります!
さあ、私たちを/dashboard/test そして、パン粉がダイナミックルートを表示するのを見ることができます


アクセス可能にする
まず第一にaria-label 価値のbreadcrumb 我々にBreadcrumb コンポーネント
import { Children } from "react";
import { Fragment } from "react";

const Breadcrumb = ({ children }) => {
  const childrenArray = Children.toArray(children);

  const childrenWtihSeperator = childrenArray.map((child, index) => {
    if (index !== childrenArray.length - 1) {
      return (
        <Fragment key={index}>
          {child}
          <span>/</span>
        </Fragment>
      );
    }
    return child;
  });

  return (
    <nav className="mx-8 md:mx-16 lg:mx-32 mt-8" aria-label="breadcrumb">
      <ol className="flex items-center space-x-4">{childrenWtihSeperator}</ol>
    </nav>
  );
};

export default Breadcrumb;
さあ、我々に小さな変更をしよう_app.js 柱に渡すBreadcrumbItem 呼ばれるisCurrent ブール値を指定します.値は、最後のパン巻き項目、つまり現在のページに対してtrueです.
import { useRouter } from "next/router";
import { useEffect, useState } from "react";
import "../styles/globals.css";
import Breadcrumb from "../components/Breadcrumb";
import BreadcrumbItem from "../components/BreadcrumbItem";

function MyApp({ Component, pageProps }) {
  const router = useRouter();
  const [breadcrumbs, setBreadcrumbs] = useState();

  useEffect(() => {
    const pathWithoutQuery = router.asPath.split("?")[0];
    let pathArray = pathWithoutQuery.split("/");
    pathArray.shift();

    pathArray = pathArray.filter((path) => path !== "");

    const breadcrumbs = pathArray.map((path, index) => {
      const href = "/" + pathArray.slice(0, index + 1).join("/");
      return {
        href,
        label: path.charAt(0).toUpperCase() + path.slice(1),
        isCurrent: index === pathArray.length - 1,
      };
    });

    setBreadcrumbs(breadcrumbs);
  }, [router.asPath]);

  return (
    <>
      <Breadcrumb>
        <BreadcrumbItem isCurrent={router.pathname === "/"} href="/">
          Home
        </BreadcrumbItem>
        {breadcrumbs &&
          breadcrumbs.map((breadcrumb) => (
            <BreadcrumbItem
              key={breadcrumb.href}
              href={breadcrumb.href}
              isCurrent={breadcrumb.isCurrent}
            >
              {breadcrumb.label}
            </BreadcrumbItem>
          ))}
      </Breadcrumb>
      <Component {...pageProps} />
    </>
  );
}

export default MyApp;
最初のホームルートについては、我々は、単にマッチングrouter.pathname with / .
現在BreadcrumbItem.jsx ファイルを次のコードに変更します
import Link from "next/link";

const BreadcrumbItem = ({ children, href, isCurrent, ...props }) => {
  return (
    <li {...props}>
      <Link href={href} passHref>
        <a
          className={isCurrent && "text-blue-500"}
          aria-current={isCurrent ? "page" : "false"}
        >
          {children}
        </a>
      </Link>
    </li>
  );
};

export default BreadcrumbItem;
ここでは、設定しているaria-current to page 現在のルートならば.

結論
私は、あなたが現在パン粉くずナビゲーションを働かせていることを望みます.それを試してみて、いい日を過ごす😁🤞

🔗 重要なリンク
  • Deployed Preview
  • GitHub Repository with the code