로고
nabongsun.shop

[nextJS] 포트폴리오 만들기(2)

1. tailwind 적용하기

pages/index.tsx

const Home = () => {
  return <div className={`text-green-500 text-lg`}>Hello nextJS!</div>;
};

export default Home;

로 바꿔보자!

아마 지금까지 똑같이 따라왔다면, tailwind 설정이 되어있지 않아 검은색으로 나올것이다.

style/globals.css

@tailwind base;
@tailwind components;
@tailwind utilities;

를 추가하고,

pages/index.tsx

import "../styles/globals.css"; //삭제할 부분

const Home = () => {
  return <div className={`text-green-500 text-lg`}>Hello nextJS!</div>;
};

export default Home;

우리의 메인페이지에 넣어보자!

그러면

글로벌 css 에러

이런 무서운 에러창이 뜰것이다!

GPT한테 물어보니, 전역CSS는 _app.js에서 가져와야 된다고 한다.

그러니깐

pages/index.tsx

const Home = () => {
  return <div className={`text-green-500 text-lg`}>Hello nextJS!</div>;
};

export default Home;

pages/_app.tsx

import type { AppProps } from "next/app";
import "../styles/globals.css";

function MyApp({ Component, pageProps }: AppProps) {
  return <Component {...pageProps} />;
}

export default MyApp;

이렇게 수정하면 tailwind 가 제대로 적용된것을 볼 수 있다.

귀엽다!

2. 만들기

아래의 일반적인 홈페이지 처럼

ALOA

보통은 헤더, 푸터 정도는 고정적으로 들어가게 되는데 그걸 만들어보자!

components
│  ├─ Nav.tsx          // 네비게이션
│  └─ Container.tsx    // 헤더,메인,푸터를 감싸는 컨테이너
data
├─ navlinks.ts         // 네비게이션의 데이터 저장
pages
├─ _app.tsx
├─ index.tsx           // mypage/
├─ a                   // mypage/a
│  └─ index.tsx
├─ b                   // mypage/b
│  ├─ index.tsx
│  └─ ab.tsx           // mypage/b/ab
├─ c                   // mypage/c
│  ├─ index.tsx
│  └─ [idx].tsx        // mypage/c/[idx]
public                 // 정적 데이터 저장
│
styles                 // css파일 저장
│
package.json

대충 이정도 만들었고/만들 예정이다. 내친김에 동적라우팅도 연습해 보자!

2.1 pages

pages/a/index.tsx

const A = () => {
  return <div className={`text-red-500 text-lg`}>A</div>;
};

export default A;

pages/b/index.tsx

const B = () => {
  return <div className={`text-blue-500 text-lg`}>B</div>;
};

export default B;


pages/b/ab.tsx

const AB = () => {
  return <div className={`text-purple-500 text-lg`}>AB</div>;
};

export default AB;


pages/c/index.tsx

const C = () => {
  return <div className={`text-pink-500 text-lg`}>C</div>;
};

export default C;


pages/c/[idx].tsx

import { useRouter } from "next/router";

const C_idx = () => {
  const router = useRouter();
  const { idx } = router.query;
  return <div className={`text-yellow-500 text-lg`}>C/{idx}</div>;
};

export default C_idx;


동적라우팅에 사용된 변수를 쓰고 싶다면 useRouter()을 통해 통째로 가져오고 useRouter().query 를 쓰면 해당 쿼리들을 모두 객체로 가져온다!

console.log(router.query);

이걸로 찍어보면

이렇게 보이는걸 보니

만약에 /pages/[a]/[b]/[c].tsx 라는 파일을 만들었다 치고,

mypage/aaa/bbb/ccc 를 들어갔다면

router.query = { a:"aaa", b:"bbb", c:"ccc" }

일것이다!

이외에도 [...c].tsx 이런식으로 만들고 mypage/ ~~ /ccc 로 들어 갈수 있는 무언가가 있지만, 딱히 필요 없을꺼 같아 설명은 생략하겠다.

2.2 data

data/navlinks.ts

const navlinks: { title: string; link: string }[] = [
  { title: "Home", link: "/" },
  { title: "Blog", link: "/blog" },
  { title: "portfolio", link: "/portfolio" },
];

export default navlinks;

드디어 타입스크립트를 사용하게 되었다. : 쓰고 해당 변수의 타입을 미리 쓰면 되나보다?

2.3 component

components/Nav.tsx

import navlinks from "../data/navlinks";
import Link from "next/link";

const Nav = () => {
  return (
    <nav>
      {navlinks.map((nav) => (
        <Link href={nav.link} key={nav.title}>
          <div className={`inline-block mr-5`}>{nav.title}</div>
        </Link>
      ))}
    </nav>
  );
};

export default Nav;

components/Container.tsx

import Head from "next/head";
import Nav from "./Nav";

const Container = (props: any) => {
  return (
    <>
      <Head>
        <title>내 블로그</title>
      </Head>
      <header>
        <Nav />
      </header>
      <main>{props.children}</main>
    </>
  );
};

export default Container;

여기까지 만들었는데 사용해야되지 않겠는가!

/pages/index.tsx

import Container from "../components/Container";

const Home = () => {
  return (
    <Container>
      <span className={`font-bold`}>HOME</span>
    </Container>
  );
};

export default Home;

이런식으로 모든 페이지들에 container를 추가해주도록 하자.

여기까지하면 아주 조악하지만 네비게이션바도 만들었다!

이제 tailwind로 조금 꾸며보도록 하자!

3.tailwind

components/Container.tsx

import Image from "next/image";
import Head from "next/head";
import Nav from "./Nav";

const Container = (props: any) => {
  return (
    <div className={`w-full flex flex-col items-center p-3`}>
      <Head>
        <title>내 블로그</title>
      </Head>
      <header
        className={`w-full max-w-screen-lg flex flex-row justify-between items-center my-1`}
      >
        <div className={`flex flex-row items-center`}>
          <Image
            src={`/logo.jpg`}
            alt="로고"
            width={40}
            height={40}
            objectFit={`cover`}
            className={`rounded-full`}
          />
          <span className={`mx-4 font-extralight`}>내 블로그</span>
        </div>
        <Nav />
      </header>
      <main className={`w-full max-w-screen-lg`}>{props.children}</main>
    </div>
  );
};

export default Container;


public에 logo.jpg 이미지를 하나 넣자.

이제 이러면 그럴싸한 헤더가 하나 만들어졌다!

다음번에는 Mixitup 효과를 이용한 페이지를 만들것이다.