【入門】ブログ開発に使えるNext.jsの基本コードいろいろ
2022-05-22
はじめに
Next.js で基本となるページ遷移やコンポーネントの実装方法を紹介します。 Next.js の環境構築や始め方については、前回のブログを参照ください。
【作成ケース ①】コンポーネントを使って複数のページで同じ内容を表示させる
ヘッダーやフッターなど、複数のページで同じ内容を表示させたいものについては、 コンポーネント という部品に分けてコードを記述できます。srcフォルダの下にcomponentsという名前でフォルダを作成し、そのフォルダ内に以下のようにファイルを作成します。
src/components/header.tsxconst Header: React.FC = () => { return ( <header> <p>ヘッダー</p> </header> ); }; export default Header;
src/components/footer.tsxconst Footer: React.FC = () => { return ( <footer> <p>フッター</p> </footer> ); }; export default Footer;
src/components/layout.tsximport Header from "./header"; import Footer from "./footer"; import { ReactNode } from "react"; type Props = { children?: ReactNode; }; const Layout: React.FC<Props> = ({ children }: Props) => { return ( <> <Header /> {children} <Footer /> </> ); }; export default Layout;
また、作成した<Layout>コンポーネントは_app.tsxファイルに以下のように記述すると全ページに適用できます。
src/pages/_app.tsximport "../styles/globals.css"; import type { AppProps } from "next/app"; import Layout from "../components/layout"; function MyApp({ Component, pageProps }: AppProps) { return ( <Layout> <Component {...pageProps} /> </Layout> ); } export default MyApp;
ここまでのコードでnpm run devで画面に表示すると、以下のような画面が表示されるかと思います。
【作成ケース ②】他のページを追加してリンクを張る
Next.js では、他のページを追加してリンクを張ることが簡単にできます。
以下のようにpagesフォルダの下にファイルやフォルダを追加していけば、それがそのままリンク先のページになります。
また、リンクを張るには、以下のように最初の行にimport Link from "next/link"と記述し、リンクを張りたい部分を<Link>タグと<a>タグで囲えば OK です。
src/pages/about.tsximport type { NextPage } from "next"; import Link from "next/link"; const About: NextPage = () => { return ( <> <h2>About Page!!</h2> <Link href="/"> <a>Home Pageへのリンク</a> </Link> </> ); }; export default About;
src/pages/index.tsximport type { NextPage } from "next"; import Link from "next/link"; const Home: NextPage = () => { return ( <> <h2>hello world!!</h2> <Link href="/about"> <a>About Pageへのリンク</a> </Link> </> ); }; export default Home;
今度は以下の画面が表示されるかと思います。About Page へのリンク をクリックすると、About ページに遷移します。
【作成ケース ③】画像ファイルを表示する
画面に表示する画像ファイルはpublicフォルダ内に格納できます。
このとき下記のようにnext/imageの Image コンポーネントを<img>タグの替わりに使うと、画面に合わせて画像を最適なサイズに縮小し、遅延ロードによって画面を読み込んだ後に表示してくれるようになります。
まず以下のようにファイルを格納します。
/public └─ sample.jpg
次にindex.tsxにて Image コンポーネントを使ってみます。
src/pages/index.tsximport type { NextPage } from "next"; import Link from "next/link"; import Image from "next/image"; const Home: NextPage = () => { return ( <> <h2>hello world!!</h2> <Link href="/about"> <a>About Pageへのリンク</a> </Link> <Image src="/sample.jpg" width={400} height={300} objectFit="contain" alt="sample" /> </> ); }; export default Home;
なお、現状の Cloudflare Pages ではnext/imageの デフォルトのイメージローダー という機能が使えません。そのままデプロイしようとすると以下のようなエラーが発生します。
Error: Image Optimization using Next.js' default loader is not compatible with `next export`.
なので、Cloudflare Pages にデプロイするソースでnext/imageを使う場合は以下のようにイメージローダーの設定が必要になります。(Vercel ではイメージローダーがデフォルトのままでも補完してくれるので、Vercel にデプロイする場合は以下の設定は不要です)
まずはnext.config.jsファイルを編集します。(赤波のエラーが発生するかもしれませんが、ひとまず無視で大丈夫です。)
next.config.js/** @type {import('next').NextConfig} */ module.exports = { reactStrictMode: true, images: { loader: "custom", }, };
次に以下のコンポーネントをcomponentsフォルダに作成します。そして実際にnext/imageの Image コンポーネントを使いたい場所では、next/imageではなくこのコンポーネントを import するようにします。loader属性に入力されたsrcとwidthを入れているだけで暫定ではありますが、とりあえずこれでnext/imageの Image コンポーネントを動作させることができます。
src/components/Image.tsximport NextImage from "next/image"; const customLoader = ({ src, width }: any) => { return `${src}?w=${width}`; }; const Image = ({ ...props }: any) => { return <NextImage {...props} loader={customLoader} />; }; export default Image;
src/pages/index.tsximport type { NextPage } from "next"; import Link from "next/link"; import Image from "../components/Image"; const Home: NextPage = () => { return ( <> <h2>hello world!!</h2> <Link href="/about"> <a>About Pageへのリンク</a> </Link> <Image src="/sample.jpg" width={400} height={300} objectFit="contain" alt="sample" /> </> ); }; export default Home;
なお、今回作成したサンプルについては、以下の GitHub のリポジトリに全コードを格納してありますので、詰まったら参考にしてみてください。