본문 바로가기

Next.js

[Next.js] 포트폴리오 사이트 만들기

오늘부터는 포트폴리오 사이트를 만들어 보려고합니다.

 

본실습은 개발하는 정대리님의 강의 영상을 참고하였습니다.

 

먼저 폴더를 하나 만들어 주고

 

 npx create-next-app@latest --experimental-app

 

를 터미널에 입력해줍니다.

 

초기 설정을 해주고 

 

npm run dev를 통해 실행합니다.

 

export default function Home() {
  return (
    <div>
      <h1>메인 페이지임</h1>
    </div>
  )
}

index.js에서 메인 페이지가 잘 동작하는지 확인하기 위해서 다음과 같이 코딩을 짰습니다.

 

localhost 페이지

잘 동작하네요!

 

레이아웃을 만들기 위해서

 

components라는 폴더를 만들어 주고, Layout.js 파일을 만들어 줍니다.

 

export default function Layout({children}) {
    return (
      <div>
        <h1>Layout</h1>
        {children}
      </div>
    )
  }

layout.js의 코드입니다.

 

children이 있는 곳에 레이아웃의 요소가 들어갈 것입니다.

 

그 다음 index.js로 가서

import Layout from './components/layout'

레이아웃을 import해오고,

 

 

export default function Home() {
  return (
    <Layout>
      <h1>메인 페이지임</h1>
    </Layout>
  )
}

가져온 Layout 태그로 내용을 감싸줍니다.

 

그리고 이제 헤더에 들어갈 내용을 만들기 위해서 header.js를 하나 만들어 줍시다.

 

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

header페이지임을 알 수 있게 다음과 같이 코드를 짜줍니다.

 

footer도 똑같이 만들어 줍시다.

 

그리고 이것들을 layout.js에서 import 해줍니다.

 

import Header from "../header"
import Footer from "../footer"
export default function Layout({children}) {
    return (
      <div>
        <Header/>
        <h1>Layout</h1>
        {children}
        <Footer/>
      </div>
    )
  }

그리고 각각 들어갈 위치에 태그를 만들어 주면 됩니다.

 

이러면 기본 세팅은 완료 되었습니다.

 

한 번 확인해 볼까요?

 

코드가 잘 적용된 모습이네요!

 

그 다음은 tailwind를 사용할 것이기 때문에 

 

tailwind를 검색 후 설치해 줍니다.

 

그러면 tailwind.config.js라는 파일이 생기는데

 

/** @type {import('tailwindcss').Config} */

  module.exports = {
    mode : 'jit',
    content: [
      "./app/**/*.{js,ts,jsx,tsx,mdx}",
      "./pages/**/*.{js,ts,jsx,tsx,mdx}",
      "./components/**/*.{js,ts,jsx,tsx,mdx}",
   
      // Or if using `src` directory:
      "./src/**/*.{js,ts,jsx,tsx,mdx}",
    ],
    darkModer:'class',
    theme: {
      extend: {},
    },
 
    plugins: [],
  }


 

이렇게 초기 설정을 해주면 됩니다.

 

그리고 global.css로 가서

 

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

이것들을 써주면 됩니다.

 

그리고 npm run dev를 다시 해줘야 합니다.

 

<h1 className="text-3xl font-bold underline">
      Hello world!
    </h1>

다음 코드를 index.js에 쓰면 tailwind가 적용 되었는지 확인할 수 있습니다.

 

밑줄이 생긴 것을 보니 성공적으로 적용된 것 같습니다.

 

그러면 이제 header를 Tailwind로 만들 수 있습니다.

 

구글에 Tailwind block이라 치면 Tailblocks라는 사이트가 나옵니다.

 

Tailblocks — Ready-to-use Tailwind CSS blocks

 

Tailblocks — Ready-to-use Tailwind CSS blocks

 

tailblocks.cc

 

헤더 메뉴에서 헤더를 하나 골라서 view code를 눌러줍니다.

 

그러면 코드가 나오는데 이것을 그대로 header.js 컴포넌트 내에 넣어주면 됩니다.

 

export default function Header() {
    return (
      <div>
       <header class="text-gray-600 body-font">
  <div class="container mx-auto flex flex-wrap p-5 flex-col md:flex-row items-center">
    <a class="flex title-font font-medium items-center text-gray-900 mb-4 md:mb-0">
      <svg xmlns="http://www.w3.org/2000/svg" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" class="w-10 h-10 text-white p-2 bg-indigo-500 rounded-full" viewBox="0 0 24 24">
        <path d="M12 2L2 7l10 5 10-5-10-5zM2 17l10 5 10-5M2 12l10 5 10-5"></path>
      </svg>
      <span class="ml-3 text-xl">Tailblocks</span>
    </a>
    <nav class="md:ml-auto flex flex-wrap items-center text-base justify-center">
      <a class="mr-5 hover:text-gray-900">First Link</a>
      <a class="mr-5 hover:text-gray-900">Second Link</a>
      <a class="mr-5 hover:text-gray-900">Third Link</a>
      <a class="mr-5 hover:text-gray-900">Fourth Link</a>
    </nav>
    <button class="inline-flex items-center bg-gray-100 border-0 py-1 px-3 focus:outline-none hover:bg-gray-200 rounded text-base mt-4 md:mt-0">Button
      <svg fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" class="w-4 h-4 ml-1" viewBox="0 0 24 24">
        <path d="M5 12h14M12 5l7 7-7 7"></path>
      </svg>
    </button>
  </div>
</header>
      </div>
    )
  }

Tailwind 적용

상단에 Header 레이아웃이 생겼습니다.

 

footer도 똑같이 진행해 줍니다.

 

export default function Footer() {
    return (
        <footer className="text-gray-600 body-font">
        <div className="container px-5 py-8 mx-auto flex items-center sm:flex-row flex-col">
          <a className="flex title-font font-medium items-center md:justify-start justify-center text-gray-900">
           
              <path d="M12 2L2 7l10 5 10-5-10-5zM2 17l10 5 10-5M2 12l10 5 10-5"></path>
           
            <span className="ml-3 text-xl">Puft's Portfolio</span>
          </a>
          <p className="text-sm text-gray-500 sm:ml-4 sm:pl-4 sm:border-l-2 sm:border-gray-200 sm:py-2 sm:mt-0 mt-4">© 2020 Tailblocks —
            <a href="https://twitter.com/knyttneve" className="text-gray-600 ml-1" rel="noopener noreferrer" target="_blank">@knyttneve</a>
          </p>
          <span className="inline-flex sm:ml-auto sm:mt-0 mt-4 justify-center sm:justify-start">
            <a className="text-gray-500">
              <svg fill="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" className="w-5 h-5" viewBox="0 0 24 24">
                <path d="M18 2h-3a5 5 0 00-5 5v3H7v4h3v8h4v-8h3l1-4h-4V7a1 1 0 011-1h3z"></path>
              </svg>
            </a>
            <a className="ml-3 text-gray-500">
              <svg fill="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" className="w-5 h-5" viewBox="0 0 24 24">
                <path d="M23 3a10.9 10.9 0 01-3.14 1.53 4.48 4.48 0 00-7.86 3v1A10.66 10.66 0 013 4s-4 9 5 13a11.64 11.64 0 01-7 2c9 5 20 0 20-11.5a4.5 4.5 0 00-.08-.83A7.72 7.72 0 0023 3z"></path>
              </svg>
            </a>
            <a className="ml-3 text-gray-500">
              <svg fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" className="w-5 h-5" viewBox="0 0 24 24">
                <rect width="20" height="20" x="2" y="2" rx="5" ry="5"></rect>
                <path d="M16 11.37A4 4 0 1112.63 8 4 4 0 0116 11.37zm1.5-4.87h.01"></path>
              </svg>
            </a>
            <a className="ml-3 text-gray-500">
              <svg fill="currentColor" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="0" className="w-5 h-5" viewBox="0 0 24 24">
                <path stroke="none" d="M16 8a6 6 0 016 6v7h-4v-7a2 2 0 00-2-2 2 2 0 00-2 2v7h-4v-7a6 6 0 016-6zM2 9h4v12H2z"></path>
                <circle cx="4" cy="4" r="2" stroke="none"></circle>
              </svg>
            </a>
          </span>
        </div>
      </footer>
    )
  }

layout도 똑같습니다.

 

Hero라는 메뉴에서 하나 골라서 적용해 줍니다.

 

<section class="text-gray-600 body-font">
  <div class="container mx-auto flex px-5 py-24 md:flex-row flex-col items-center">
    <div class="lg:flex-grow md:w-1/2 lg:pr-24 md:pr-16 flex flex-col md:items-start md:text-left mb-16 md:mb-0 items-center text-center">
      <h1 class="title-font sm:text-4xl text-3xl mb-4 font-medium text-gray-900">Before they sold out
        <br class="hidden lg:inline-block">readymade gluten
      </h1>
      <p class="mb-8 leading-relaxed">Copper mug try-hard pitchfork pour-over freegan heirloom neutra air plant cold-pressed tacos poke beard tote bag. Heirloom echo park mlkshk tote bag selvage hot chicken authentic tumeric truffaut hexagon try-hard chambray.</p>
      <div class="flex justify-center">
        <button class="inline-flex text-white bg-indigo-500 border-0 py-2 px-6 focus:outline-none hover:bg-indigo-600 rounded text-lg">Button</button>
        <button class="ml-4 inline-flex text-gray-700 bg-gray-100 border-0 py-2 px-6 focus:outline-none hover:bg-gray-200 rounded text-lg">Button</button>
      </div>
    </div>
    <div class="lg:max-w-lg lg:w-full md:w-1/2 w-5/6">
      <img class="object-cover object-center rounded" alt="hero" src="https://dummyimage.com/720x600">
    </div>
  </div>
</section>

이렇게 코드가 생길텐데 br부분 끝부분에 '/'를 추가해주고,

 

input 태그는 없애줍니다.

 


import { Inter } from 'next/font/google'
import Layout from './components/layout'
const inter = Inter({ subsets: ['latin'] })

export default function Home() {
  return (
    <Layout>
     <section className="text-gray-600 body-font">
  <div className="container mx-auto flex px-5 py-24 md:flex-row flex-col items-center">
    <div className="lg:flex-grow md:w-1/2 lg:pr-24 md:pr-16 flex flex-col md:items-start md:text-left mb-16 md:mb-0 items-center text-center">
      <h1 className="title-font sm:text-4xl text-3xl mb-4 font-medium text-gray-900">Before they sold out
        <br className="hidden lg:inline-block"/>readymade gluten
      </h1>
      <p className="mb-8 leading-relaxed">Copper mug try-hard pitchfork pour-over freegan heirloom neutra air plant cold-pressed tacos poke beard tote bag. Heirloom echo park mlkshk tote bag selvage hot chicken authentic tumeric truffaut hexagon try-hard chambray.</p>
      <div className="flex justify-center">
        <button className="inline-flex text-white bg-indigo-500 border-0 py-2 px-6 focus:outline-none hover:bg-indigo-600 rounded text-lg">Button</button>
        <button className="ml-4 inline-flex text-gray-700 bg-gray-100 border-0 py-2 px-6 focus:outline-none hover:bg-gray-200 rounded text-lg">Button</button>
      </div>
    </div>
    <div className="lg:max-w-lg lg:w-full md:w-1/2 w-5/6">
     
    </div>
  </div>
</section>
    </Layout>
  )
}

한 번 확인해 볼까요?

 

Header, Layout, Footer가 모두 적용 되었습니다!

 


import { Inter } from 'next/font/google'
import Layout from './components/layout'
const inter = Inter({ subsets: ['latin'] })

export default function Home() {
  return (
    <Layout>
     <section className="flex min-h-screen flex-col items-center justify-center text-gray-600 body-font">
  <div className="container mx-auto flex px-5 py-24 md:flex-row flex-col items-center">
    <div className="lg:flex-grow md:w-1/2 lg:pr-24 md:pr-16 flex flex-col md:items-start md:text-left mb-16 md:mb-0 items-center text-center">
      <h1 className="title-font sm:text-4xl text-3xl mb-4 font-medium text-gray-900">안녕하세요 Puft입니다!
        <br className="hidden lg:inline-block"/>Productive Use of Free time
      </h1>
      <p className="mb-8 leading-relaxed">명령·규칙 또는 처분이 헌법이나 법률에 위반되는 여부가 재판의 전제가 된 경우에는 대법원은 이를 최종적으로 심사할 권한을 가진다. 법률안에 이의가 있을 때에는 대통령은 제1항의 기간내에 이의서를 붙여 국회로 환부하고, 그 재의를 요구할 수 있다. 국회의 폐회중에도 또한 같다.

</p>
      <div className="flex justify-center">
        <button className="inline-flex text-white bg-indigo-500 border-0 py-2 px-6 focus:outline-none hover:bg-indigo-600 rounded text-lg">
          프로젝트 보러가기</button>
       
      </div>
    </div>
    <div className="lg:max-w-lg lg:w-full md:w-1/2 w-5/6">
     
    </div>
  </div>
</section>
    </Layout>
  )
}

하드 코딩으로 텍스트를 조금 바꿔보겠습니다!

 

적용된 모습입니다.

 

내용이 길어져서 다음 시간에 이어서 하겠습니다!

 

감사합니다