Blanc

Next.js + Typescript + microCMSでJamstackブログを作ってみた Part2

サムネイル

はじめに

この記事は複数に分かれています。
前回までの記事をご覧になっていない場合はそちらの記事を読んでいただいた方が流れがわかると思います。

今回やること

  • Styled-componetsのインストール
  • Headerの作成
  • Fotterの作成
  • Layoutの作成
  • Headの設定


Styled-components

Next.jsのプロジェクトでは様々なスタイルの適用方法があります。
今回はCSS in JSの中でも有名なStyled-componentsというものを使用します。

インストール

npm install --save styled-components

型定義ように以下もインストールしておきます

npm install --save-dev @types/styled-components

Styled-componentsはサーバーサイドでは動かないためサーバーサイドでも動くように設定をしていきます

npm install --save-dev babel-plugin-styled-components

.babelrcファイルをルートディレクトリ(package.jsonを同じ階層)に作成します。
中に以下を記述
.babelrc

{
  "presets": ["next/babel"],
  "plugins": [
    [
      "babel-plugin-styled-components",
      {
        "ssr": true,
        "displayName": true
      }
    ]
  ]
}

これでStyled-componentsの設定は以上です。

GlobalStylesの作成

stylesディレクトリの下にGlobalStyles.jsを作成
src > styles > GlobalStyles.js

import { createGlobalStyle } from 'styled-components';

const GlobalStyles = createGlobalStyle`
*{
    padding: 0;
    margin: 0;
    box-sizing: border-box;
  }
  :root{
    --primary: #707070;
    --subprimary: #DFDFDF;
    --blue: #007ACC;
    --white : #ffffff;
    --black: #000000;
  }
  html{
    font-size: 10px;
    height: 100vh;
  }
  body{
    background-color: var(--white);
    font-family: 'Roboto Mono';
    color: var(--black);
    letter-spacing: 0.1em;
  }
  ul,li{
    list-style: none;
  }
  a{
    text-decoration: none;
    color: var(--black);
  }
  img{
    width: 100%;
    height: 100%;
    object-fit: cover;
  }
  button{
    outline: none
  }
`;
export default GlobalStyles;

共通のスタイルはここに書いておきます
使用する色はこのように管理しておきます。

  :root{
    --primary: #707070;
    --subprimary: #DFDFDF;
    --blue: #007ACC;
    --white : #ffffff;
    --black: #000000;
  }

呼び出し方

color:var(--primary)

var()の中に:rootの内で管理している色を呼び出します

Headerコンポーネントを作成する

src以下にcomponensディレクトリを作成
componentsの中にLayoutディレクトリを作成
その下に全ページで共通して表示するものを入れていきます
Header.tsxをLayoutディレクトリの下に作成する
src > components > layout >Header.tsx

import Link from 'next/link';
import styled from 'styled-components';
// --------------- Function ---------------
export default function Header() {
  return (
    <HeaderStyles>
      <Link href='/'>
        <a>LOGO</a>
      </Link>
    </HeaderStyles>
  )
}
// --------------- Styles ---------------
const HeaderStyles = styled.header`
  width: 100%;
  height: 60px;
  display: flex;
  align-items: center;
  padding: 0 4rem;
`;


Footerコンポーネントを作成

layoutディレクトリの下にFotter.tsxを作成
src > components > layout >Footer.tsx

import styled from 'styled-components';
// --------------- Function ---------------
export default function Footer() {
  return (
    <FooterStyles>
      <p><small>&copy;2021 TestBlog</small></p>
    </FooterStyles>
  )
}

// --------------- Styles ---------------
const FooterStyles = styled.footer`
  width: 100%;
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: var(--primary);
  color: var(--white);
`;


Layoutの作成

Layoutはどのページでも共通して表示するものです。
例えばheaderやfooter、お問い合わせのコンポーネントはどのページでも共通して表示してあることが多いと思います。
Layoutを使わない場合はpage以下にあるファイル全てにheaderコンポーネント等をインポートしなければなりせん。
layoutディレクトリ以下にLayout.tsxを作成
src > components > layout >Layout.tsx

import { PropsWithChildren } from 'react';
import GlobalStyles from '../../styles/GlobalStyles';
import Footer from './Footer';
import Header from './Header';
// --------------- Function ---------------
export default function Layout({ children }: PropsWithChildren<any>) {
  return (
    <>
      <GlobalStyles />
      <Header />
      <main>{children}</main>
      <Footer />
    </>
  );
}

Layoutコンポーネントのpropsをchildrenとして、mainタグの中で呼び出します。
こうすることでLayoutコンポーネントで囲んだ中身がchildrenとしてLayoutに渡されます。
GlobalStylesコンポーネントを呼び出しておくことでスタイルが適用されます。


全ページに適用させる

_app.tsxは全ページに適用させたい処理などを書くときに使用されます
そのため、ここで使用されているコンポーネントをLayoutコンポーネントで囲むことで全ページに適用させます
pages > _app.tsx

import type { AppProps } from 'next/app';
import Layout from '../components/layouts/Layout';
function MyApp({ Component, pageProps }: AppProps) {
  return (
    <Layout>
      <Component {...pageProps} />
    </Layout>
  );
}
export default MyApp;


index.tsxを編集

トップページに当たるindex.tsxを編集します。
pages > index.tsx

export default function Home() {
  return (
    <div>
      <h1>Hello</h1>
    </div>
  )
}

とりあえずHelloとだけ表示させておきましょう。
開発サーバーを立ち上げ、headerとfooter、スタイルが適応されていることを確認しましょう

npm run dev


Headの設定

HTMLではheadタグに当たるものがNext.jsにはありません。
そのためサイトタイトルやメタデータを記述するためにはHeadを読み込む必要があります
今回は全ページ共通のHeadを作成するため、Layoutに設置していきます。
src > components > layout >Layout.tsx

// 追加
import Head from 'next/head';

import { PropsWithChildren } from 'react';
import GlobalStyles from '../../styles/GlobalStyles';
import Footer from './Footer';
import Header from './Header';
// --------------- Function ---------------
export default function Layout({ children }: PropsWithChildren<any>) {
  return (
    <>
      <Head>
        <title>Next Blog</title>
        <meta name='description' content='Generated by create next app' />
        <link
          rel='icon'
          href='https://emojipedia-us.s3.dualstack.us-west-1.amazonaws.com/thumbs/120/apple/285/whale_1f40b.png'
        />
      </Head>
      // 省略
   </>
    );
  }

Headコンポーネントの中にHTMLで書いているのと同じように記述することができます。
faviconはこちらのサイトを使用させていただいています。
画像のURLをコピーして貼り付けています。

まとめ

今回から本格的に作成に入っていきました。
これから少し難しくなりますが、頑張りましょう。

Back To List
  • タグ画像
  • タグ画像
  • タグ画像