※ Next.JS의 공식문서 튜토리얼을 번역합니다
※ 각 챕터 내 Setup 파트는 생략했습니다. 실습하던 프로젝트로 계속 진행하시면 됩니다.
※ 필자 입맛대로 한 번역이므로 주의 요함
※ 오역, 오타에 대한 피드백 두 팔 벌려 환영
React로 완벽한 웹 어플리케이션을 만들기 위해서는 많은 세부사항을 고려해야 합니다.
프레임워크는 이러한 문제들을 해결해 줍니다. 하지만 이런 프레임워크는 적정 수준의 추상화 레벨을 가지고 있어야 합니다. 그렇지 않다면 그건 딱히 유용하지 않을 거예요. 또한 프레임워크는 코드를 작성하면서 당신과 당신 팀이 멋진 경험을 보장하는 탁월한 "개발 경험"을 시켜 주어야 해요.
Next.js는 리액트 프레임워크입니다. Next.js는 위에 언급된 모든 문제들을 해결해 주죠. 하지만 가장 중요한 건, Next.js는 당신과 당신 팀이 리액트 어플리케이션을 빌드하는 데에 있어 극락을 경험시켜 줄 거라는 거죠.
Next.js는 최고의 개발자 경험과 많은 빌트인 기능을 제공하는 것을 목표로 합니다.
먼저, 개발환경을 준비합시다.
Next.js 앱을 생성하기 위해, 터미널을 열고 cd
명령어를 통해 앱을 생성하고 싶은 곳의 디렉토리 경로를 지정한 후, 아래의 명령어를 실행시킵니다.
npx create-next-app nextjs-blog --use-npm --example "https://github.com/vercel/next-learn/tree/master/basics/learn-starter
명령어를 자세히 보면,
create-next-app
이라는 툴을 사용하고 있는데, 이건 Next.js 앱을 새로 생성할 때 필요한 것들을 알아서 설치해 주는 CLI 툴입니다. 또한--example
이라는 옵션을 통해 이 템플릿을 사용하도록 하고 있죠.
자, 이제 nextjs-blog
라는 새로운 디렉토리가 생겼습니다. cd
를 이용해 해당 디렉토리 안으로 들어가 주세요.
cd nextjs-blog
그런 다음, 아래의 명령어를 입력해 주세요.
npm run dev
그럼 당신의 Next.js 앱의 개발 서버가 3000번 포트에서 실행됩니다. 작동하는지 확인해 봅시다. 브라우저에서 http://localhost:3000를 열어 보세요.
http://localhost:3000로 접속했을 때, 아래와 같은 페이지가 보여야 해요. 해당 템플릿 페이지는 Next.js에 관한 유용한 정보를 담고 있죠.
시작 페이지를 편집해 봅시다.
pages/index.js
파일을 열어 주세요.<h1>
태그 아래의 "Welcome to" 라고 쓰인 텍스트를 "Learn" 으로 수정해 보세요.파일을 저장하자마자, 브라우저는 수정된 페이지를 자동적으로 업데이트합니다.
Next.js 개발 서버는 Fast Refresh가 가능합니다. 당신이 파일을 수정하게 되면, Next.js는 브라우저로 하여금 눈깜짝할 사이에 수정사항을 반영시켜요. 새로고침이 필요 없죠!
튜토리얼을 계속 진행하기 위해선 개발서버가 돌아가고 있어야 하지만, 서버를 새로 작동시키고 싶다면
Ctrl+c
를 눌러 서버를 멈출 수 있습니다.
지금까지 우리가 만든 Next.js 앱은 하나의 페이지 뿐이었어요. 일반적으로 웹사이트와 웹 어플리케이션은 여러 개의 페이지를 가지고 있죠.
페이지 추가 방법에 대해 알아 봅시다.
이 레슨을 통해,
Link
컴포넌트를 사용하여 페이지 간의 클라이언트 사이드 네비게이션을 어떻게 가능하게 하는지 배웁니다.Next.js에서 페이지란 pages
폴더 내의 파일에서 export 되어진 리액트 컴포넌트입니다.
페이지들은 각자의 파일명에 기반하여 라우팅 됩니다. 예를 들어, 개발 단계에서
pages/index.js
는 /
로 라우팅 됩니다. pages/posts/first-post.js
는 /posts/first-post
로 라우팅 됩니다. pages/index.js
파일은 이미 존재하고 있으니, pages/posts/first-post.js
를 생성하여 라우팅 기능을 살펴 봅시다.
pages
폴더 아래에 posts
폴더를 생성합니다.
posts
폴더 안에 first-post.js
라는 파일을 만들고 아래의 코드를 넣어 주세요.
export default function FirstPost() {
return <h1>First Post</h1>
}
컴포넌트는 어떤 이름이든 가질 수 있지만, 반드시 export default
형태로 export 되어야 합니다.
자, 개발 서버가 제대로 돌고 있는지 확인하고, http://localhost:3000/posts/first-post로 접속해 보세요. 아래와 같은 페이지가 보여야 해요.
이게 Next.js에서 다른 페이지를 생성하는 방법이에요.
pages
폴더 아래에 JS 파일을 생성하면, 그 파일의 경로가 URL path가 되는 겁니다.
이건 HTML과 PHP 파일을 사용하여 웹사이트를 만드는 것과 비슷한 방법이에요. HTML을 작성하는 대신 JSX 문법과 리액트 컴포넌트를 사용하는 거죠.
이제 네비게이션을 위해 새로 생성한 페이지에 링크를 추가해 봅시다.
웹사이트에서 페이지를 연결시킬 때, <a>
라는 HTML 태그를 사용합니다.
Next.js에서는 next/link
로부터 Link
컴포넌트를 가져와 <a>
태그를 감싸야 합니다. <Link>
는 어플리케이션 내에서 다른 페이지로의 클라이언트 사이드 네비게이션이 가능하도록 해 줍니다.
<Link>
먼저, pages/index.js
파일을 열고, 페이지 상단에 아래의 코드를 추가하여next/link
로부터 Link
컴포넌트를 import 합시다.
import Link from 'next/link'
그리고 아래와 같은 h1
태그를 찾아서,
<h1 className="title">
Learn <a href="https://nextjs.org">Next.js!</a>
</h1>
다음과 같이 바꿔 주세요.
<h1 className="title">
Read{' '}
<Link href="/posts/first-post">
<a>this page!</a>
</Link>
</h1>
{''}
여러 줄로 된 텍스트를 나누는 데에 쓰일 공란을 추가합니다.
다음으로, pages/posts/first-post.js
를 열고 기존의 코드를 아래의 코드로 치환해 줍니다.
import Link from 'next/link'
export default function FirstPost() {
return (
<>
<h1>First Post</h1>
<h2>
<Link href="/">
<a>Back to home</a>
</Link>
</h2>
</>
)
}
Link
컴포넌트는 <a>
태그 사용법과 비슷하긴 하지만, <a href="...">
대신에 <Link href="...">
사용하고 그 안에 <a>
태그를 넣어 줍니다.
제대로 작동하는지 확인해 봅시다. 각 페이지 내에 뒤로 가기와 앞으로 가기를 가능하게 하는 링크가 있어야 해요.
Link
컴포넌트는 동일한 Next.js 앱 내에서 두 개의 페이지 간에 클라이언트 사이드 네비게이션이 가능하게 해 줍니다.
클라이언트 사이드 네비게이션이란 자바스크립트를 사용한 페이지 전환을 의미하는데, 이는 브라우저에 의한 기본 네비게이션보다 더 빠르게 작동합니다.
이를 확인해 볼 수 있는 간단한 방법이 있어요.
<HTML>
의 background
CSS 속성을 yellow
로 변경해 주세요.이는 브라우저가 전체 페이지를 로드하지 않으며 클라이언트 사이드 네비게이션이 작동하고 있음을 보여 줍니다.
만일 <Link href="...">
대신 <a href="...">
를 사용했다면, 링크 클릭시 배경색은 사라졌을 겁니다. 브라우저가 전체 새로고침 되기 때문이죠.
Next.js는 자동적으로 코드 스플리팅을 합니다. 그래서 해당 페이지에 필요한 것만 불러옵니다. 홈페이지가 렌더링 될 때, 다른 페이지를 위한 코드는 가져오지 않습니다.
이는 당신이 아무리 수많은 페이지를 갖고 있더라도 홈페이지의 신속한 로드를 보장해 줍니다.
사용자가 요청한 페이지에 대한 코드만 가져온다는 것은 페이지는 분리 상태가 된다는 것을 의미합니다. 만일 특정 페이지가 에러를 발생시킨다 해도, 나머지 페이지는 작동할 겁니다.
더군다나, Next.js의 운영 빌드에서 언제든 브라우저의 뷰포트에 Link
컴포넌트가 나타난다면, Next.js는 백그라운드에 그 링크에 연결된 페이지에 대한 코드를 자동적으로 프리패치(prefetch) 합니다. 그래서 링크를 클릭하게 되면, 해당 페이지의 코드가 미리 백그라운드에 로드되어 있기에, 페이지 전환이 거의 즉각적으로 이루어지게 됩니다.
Next.js는 최고의 퍼포먼스를 위해 코드 스플리팅, 클라이언트 사이드 네비게이션, 프리페칭(운영에서)으로써 당신의 어플리케이션을 최적화합니다.
당신은 pages
폴더 아래에 파일로 라우팅을 구현할 수 있고, 빌트인 <Link>
컴포넌트를 사용할 수 있습니다. 라우팅 라이브러리는 필요하지 않죠.
next/link
에 대한 API reference와 라우팅 문서에서 Link
컴포넌트에 대해 더 알아볼 수 있습니다.
Note : 만일 Next.js 앱 외부 페이지로 링크를 걸어야 한다면,
Link
없이<a>
태그를 사용하면 됩니다.
만일className
과 같은 속성을 추가하고자 한다면,Link
가 아닌<a>
태그에 추가하면 됩니다.
우리가 추가한 두 번째 페이지는 현재 어떤 스타일링도 되어 있지 않아요. 이 페이지에 CSS 작업을 추가해 봅시다.
Next.js는 CSS와 Sass에 대한 내장 지원을 가지고 있습니다. 이번 과정에선 CSS를 사용할 겁니다.
또한 이 레슨에선 Next.js가 어떻게 이미지 파일이나 title
태그와 같은 페이지 메타데이터 등의 정적 파일을 다루는지에 대해 배워볼 겁니다.
이 레슨에서, 당신은 아래와 같은 것을 배우게 될 거예요.
<head>
태그를 커스터마이징하는 방법pages/_app.js
내에 전역 CSS를 추가하는 방법Next.js에서의 스타일링에 대한 자세한 문서가 필요하다면, 이 CSS 문서를 읽어 보세요.
Next.js는 최상위 레벨의 public
폴더 안에 있는 정적 파일을 사용합니다. public
폴더 안에 있는 파일들은 pages
와 같은 어플리케이션의 루트 폴더에서 참고될 수 있습니다.
public
폴더는 robots.txt
, Google Site Verification, 그리고 다른 정적 파일에 있어 유용합니다. 자세한 내용은 정적 파일 서빙에 대한 문서를 확인해 보세요.
먼저, 당신의 프로필 이미지를 가져와 봅시다.
.jpg
확장자의 이미지 파일을 다운로드하세요. public
폴더 안에 images
폴더를 생성하세요.public/images
폴더 안에 profile.jpg
라는 이름으로 저장해 주세요.public
폴더 아래의 사용하지 않는 SVG 로고 파일은 지워도 돼요.보통의 HTML에선 아래와 같이 프로필 파일을 추가했을 거예요.
<img src="/images/profile.jpg" alt="Your Name" />
그리고 당신이 직접 다음과 같은 항목의 작업들을 처리했어야 하죠.
대신에 Next.js는 당신으로 하여금 위의 과정에서 벗어나게 해 줄 Image
컴포넌트를 제공합니다.
next/image
는 HTML의 <img>
엘리먼트의 확장형이자 모던 웹을 위해 진화한 컴포넌트입니다.
또한 Next.js는 이미지 최적화를 기본으로 지원합니다. 이미지의 리사이징과 최적화, 그리고 브라우저의 지원 여부에 따라 WebP와 같은 모던 포맷의 이미지 또한 제공이 가능합니다. 이는 작은 뷰포트를 가진 기기에서 큰 사이즈의 이미지가 로드되는 것을 방지합니다. 또한 Next.js는 자동적으로 차세대 이미지 포맷을 채택하고 그 포맷을 지원하는 브라우저에 해당 이미지를 제공합니다.
자동 이미지 최적화는 모든 이미지 형식에 적용됩니다. 이미지가 CMS와 같은 외부 데이터 소스로부터 호스팅 됐다 해도 최적화가 돼요.
Next.js는 빌드 타임에 이미지를 최적화하는 대신 사용자가 이미지를 요청하는 때에 최적화 작업을 합니다. 당신이 제공하는 이미지가 열 장이든 천만 장이든, 다른 정적 사이트 생성기와는 다르게 당신의 빌드 타임은 증가하지 않습니다.
이미지는 원래 지연되어 로드됩니다. 이는 페이지 속도가 뷰포트를 벗어나는 이미지 때문에 불이익을 받는 건 아니라는 겁니다. 이미지는 뷰포트 내로 스크롤될 때 로드됩니다.
아래는 next/image
를 사용하여 우리의 프로필 사진을 보여주기 위한 예제 코드입니다. height
와 width
프롭스는 원본 이미지와 동일한 비율을 가진 렌더링 사이즈여야 합니다.
Note: 이 컴포넌트는 나중에 "Polishing Layout"에서 사용할 거니깐, 아직 복사할 필요 없습니다.
import Image from 'next/image'
const YourComponent = () => (
<Image
src="/images/profile.jpg" // Route of the image file
height={144} // Desired size with correct aspect ratio
width={144} // Desired size with correct aspect ratio
alt="Your Name"
/>
)
만일 <title>
태그와 같은 페이지의 메타데이터를 수정하고 싶으면 어떻게 해야 할까요?
<title>
은 <head>
태그의 일부입니다. Next.js에서 <head>
태그를 어떻게 수정하는지 알아 봅시다.
pages/index.js
파일을 열고 아래의 코드를 찾아 보세요.
<Head>
<title>Create Next App</title>
<link rel="icon" href="/favicon.ico" />
</Head>
<Head>
가 <head>
대신에 사용된 게 보일 거예요. <Head>
는 Next.js 내에 빌트되어 있는 리액트 컴포넌트입니다. 이 컴포넌트로 페이지의 <head>
를 수정할 수 있어요.
Head
컴포넌트는 next/head
모듈로부터 가져올 수 있습니다.
아직 posts/first-post
라우트 내에 <title>
태그를 넣지 않았죠? 해 봅시다.
pages/posts/first-post.js
파일을 열고 파일의 시작 부분에 next/head
로부터 Head
컴포넌트를 임포트 해 오겠다는 코드를 추가해 주세요.
import Head from 'next/head'
그리고, FirstPost
컴포넌트가 Head
컴포넌트를 포함하도록 업데이트 해 주세요. 이제 title
태그만 추가하면 됩니다.
export default function FirstPost() {
return (
<>
<Head>
<title>First Post</title>
</Head>
<h1>First Post</h1>
<h2>
<Link href="/">
<a>Back to home</a>
</Link>
</h2>
</>
)
}
이 URL로 접속해 보세요. 브라우저 탭에 "First Post"라고 적혀 있을 거예요. 브라우저의 개발자 도구를 통해서도 <head>
안에 title
태그가 추가된 걸 확인할 수 있습니다.
써드파티 자바스크립트는 써드파티 소스로부터 추가된 모든 스크립트를 의미합니다. 보통, 써드파티 스크립트는 사이트에
Next.js 앱에 써드파티 스크립트를 어떻게 추가할 수 있는지 알아 봅시다.
pages/posts/first-post.js
파일에서 아래의 코드를 찾아 주세요.
<Head>
<title>First Post</title>
</Head>
메타데이터 말고도, 즉시 로드되고 실행되어야 하는 스크립트도 또한 일반적으로 페이지의 <head>
태그 내에 추가합니다. 일반적인 <script>
엘리먼트를 사용해서 외부 스크립트를 가져올 때는 아래와 같이 하죠.
<Head>
<title>First Post</title>
<script src="https://connect.facebook.net/en_US/sdk.js" />
</Head>
이 스크립트는 페이스 북의 소셜 플러그인과 다른 기능을 위해 흔히 쓰이는 Facebook SDK 입니다. 이 방식도 작동은 하지만, 동일 페이지의 다른 자바스크립트 코드에 대해
next/script
는 <script>
엘리먼트의 확장형이자 다른 스크립트를 불러오거나 실행할 때 최적화 해 줍니다.
같은 파일의 상단에 next/script
로부터 Script
를 불러오는 코드를 추가해 주세요.
import Script from 'next/script'
이제, FirstPost
컴포넌트 안에 Script
컴포넌트를 추가해 줍니다.
export default function FirstPost() {
return (
<>
<Head>
<title>First Post</title>
</Head>
<Script
src="https://connect.facebook.net/en_US/sdk.js"
strategy="lazyOnload"
onLoad={() =>
console.log(`script loaded correctly, window.FB has been populated`)
}
/>
<h1>First Post</h1>
<h2>
<Link href="/">
<a>Back to home</a>
</Link>
</h2>
</>
)
}
Script 컴포넌트에 정의된 몇 가지 속성을 알아 봅시다.
strategy
는 언제 써드파티 스크립트를 로드할지를 컨트롤 합니다. lazyOnload
라는 값은 Next.js로 하여금 이 스크립트를 브라우저의 유휴 시간에 불러오도록 명령합니다.onLoad
는 스크립트의 로딩이 끝나는 즉시 자바스크립트 코드를 실행 시킵니다. 이 예제에선 스크립트 로드가 제대로 되었다는 문구를 콘솔창에 찍히도록 해 두었습니다.이 URL에 접속해 보세요. 브라우저의 개발자 도구의 Console 패널에 메시지가 찍히는 걸 확인할 수 있습니다. 또한 window.FB
를 통해 스크립트가 전역 변수에서 담겨 있는 것을 볼 수 있습니다.
Note: 페이스북 SDK는 써드파티 스크립트를 앱에 어떻게 추가하는지를 익히기 위해 고안한 예제입니다. Next.js의 써드파티 기능에 대해 이해가 되었다면, 다음 과정 진행에 앞서 FirstPost
에서 해당 Script 컴포넌트를 삭제해도 좋습니다.
CSS 스타일링에 대해 얘기해 봅시다.
여러분도 봤듯, 우리의 인덱스 페이지는 이미 스타일링 작업이 좀 되어 있어요. pages/index.js
파일을 보면 아래와 같은 코드가 보일 겁니다.
<style jsx>{`
…
`}</style>
이 페이지는 styled-jsx라는 라이브러리를 사용했습니다. 이건 'CSS-in-JS' 라이브러리인데, 리액트 컴포넌트 내에 CSS를 작성할 수 있게 해 주고, CSS 범위는 해당 컴포넌트로 한정되어 집니다. (다른 컴포넌트는 영향 받지 않는다는 뜻)
Next.js는 style-jsx를 내장 지원하지만, styled-components 혹은 emotion과 같은 다른 유명 CSS-in-JS 라이브러리도 사용할 수 있습니다.
Next.js는 CSS와 Sass를 내장 지원합니다. .css
와 .scss
파일의 import를 허용해 주죠.
Tailwind CSS와 같은 유명 CSS 라이브러리도 지원합니다.
이 과정에서, 우리는 어떻게 Next.js에서 CSS 파일을 작성하고, import 하는지에 대해 알아볼 겁니다. Next.js의 내장 지원인 CSS Modules과 Sass도 알아볼 거예요.
첫 번째로, 모든 페이지에서 사용될 Layout 컴포넌트를 생성해 봅시다.
components
라는 이름의 최상위 레벨 폴더를 생성해 주세요.components
안에 layout.js
라는 파일을 만들고, 아래의 코드를 복사해 주세요.export default function Layout({ children }) {
return <div>{children}</div>
}
그런 다음, pages/posts/first-post.js
파일을 열고, Layout
컴포넌트를 import한 후, 가장 바깥쪽 컴포넌트로 만드세요.
import Head from 'next/head'
import Link from 'next/link'
import Layout from '../../components/layout'
export default function FirstPost() {
return (
<Layout>
<Head>
<title>First Post</title>
</Head>
<h1>First Post</h1>
<h2>
<Link href="/">
<a>Back to home</a>
</Link>
</h2>
</Layout>
)
}
이제, Layout
컴포넌트에 스타일링을 해 봅시다. 리액트 컴포넌트에 CSS 파일을 import 해 주는 CSS Modules를 사용할 겁니다.
components
폴더에 layout.module.css
파일을 생성하고, 아래의 코드를 넣어 주세요.
.container {
max-width: 36rem;
padding: 0 1rem;
margin: 3rem auto 6rem;
}
중요 CSS Modules를 쓰기 위해선, CSS 파일 이름이 반드시
.module.css
로 끝나야 합니다.
container
클래스를 components/layout.js
에서 사용하기 위해선,
styles
라는 이름으로 import 해 옵니다.styles.container
를 className
으로써 사용합니다.components/layout.js
파일을 열고, 아래 코드로 덮어 씌워 주세요.
import styles from './layout.module.css'
export default function Layout({ children }) {
return <div className={styles.container}>{children}</div>
}
이 URL로 접속하면, 텍스트가 컨테이너의 중앙에 위치해 있는 걸 볼 수 있습니다.
브라우저의 개발자도구에서 HTML을 본다면, Layout
컴포넌트에 의해 렌더링 된 div
의 클래스명이 layout_container__...
와 같은 식으로 되어 있는 게 보일 거예요.
CSS Modules
가 그렇게 한 겁니다. 자동적으로 고유한 클래스 명을 생성하거든요. CSS Modules를 사용하는 한, 클래스명 중복 같은 건 걱정하지 않아도 돼요.
더군다나, Next.js의 코드 스플리팅 기능은 CSS Modules에서도 잘 작동합니다. 각 페이지에 대한 최소량의 CSS를 로드해 오는 것을 보장하죠. 이는 곧 작은 번들 사이즈로 귀결됩니다.
CSS Modules는 빌드 타임 때 자바스크립트 번들에서 꺼내져 오고 Next.js에 의해 자동적으로 로드된 .css
파일들을 생성합니다.
CSS Modules는 컴포넌트 레벨 스타일에 유용합니다. 하지만 모든 페이지에 사용할 CSS 코드가 필요하다면? 이또한 Next.js는 할 수 있습니다.
전역 CSS 파일을 불러오기 위해선, pages/_app.js
라는 파일을 생성하고 아래의 코드를 넣어 주세요.
export default function App({ Component, pageProps }) {
return <Component {...pageProps} />
}
App
컴포넌트는 다른 페이지들에 공통적으로 적용될 상위 레벨 컴포넌트입니다. 예를 들면, 페이지 이동이 이뤄질 떼 상태 유지를 위해 App
컴포넌트를 사용합니다.
중요: pages/_app.js
를 추가하는 경우 개발 서버를 재시작해야 합니다. Ctrl+c
를 눌러 서버를 재시작시키세요.
Next.js에서 전역 CSS를 추가하기 위해선 pages/_app.js
에 전역 CSS 파일을 import 해 와서 사용합니다. 아무 곳에서나 전역 CSS를 import 할 수 없습니다. pages/_app.js
가 아닌 곳에서 전역 CSS를 import 할 수 없는 이유는 전역 CSS가 페이지의 모든 엘리먼트에 영향을 끼치기 때문입니다.
만일 메인 페이지에서 /posts/first-post
페이지로 이동한다면, 메인 페이지에 대한 전역 스타일링 코드가 /posts/first-post
에 의도치 않게 영향을 끼칠 수도 있어요.
전역 CSS 파일은 어느 경로에 있어도 되고, 어떤 이름을 써도 좋아요. 따라해 봅시다.
styles
라는 상위 폴더 안에 global.css
파일을 생성해 주세요.styles/global.css
파일 안에 아래의 코드를 넣어 주세요. 아래 코드는 몇몇 요소의 스타일을 초기화하고 a
태그의 폰트 색상을 변경합니다. html,
body {
padding: 0;
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, Ubuntu,
Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
line-height: 1.6;
font-size: 18px;
}
* {
box-sizing: border-box;
}
a {
color: #0070f3;
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
img {
max-width: 100%;
display: block;
}
마지막으로 pages/_app.js
를 열고 CSS를 다음과 같이 import 시키세요.
import '../styles/global.css'
export default function App({ Component, pageProps }) {
return <Component {...pageProps} />
}
이제 이 URL로 접속하면, 스타일링이 아래와 같이 적용된 걸 볼 수 있습니다.
작동하지 않는다면,
pages/_app.js
파일을 추가하고 개발서버를 재시작했는지 확인해 보세요.
지금까지 우리는 최소한의 리액트 코드와 CSS 코드를 추가해 왔습니다. 데이터 가져오기라는 다음 과정으로 넘어가기 전에, 우리 페이지의 스타일링과 코드를 다듬어 보죠.
components/layout.module.css
components/layout.module.css
파일을 열고, 레이아웃과 프로필 이미지를 위해 좀 더 다듬어 진 아래의 스타일링 코드로 덮어 씌워 주세요.
.container {
max-width: 36rem;
padding: 0 1rem;
margin: 3rem auto 6rem;
}
.header {
display: flex;
flex-direction: column;
align-items: center;
}
.backToHome {
margin: 3rem 0 0;
}
styles/utils.module.css
두 번째로는 타이포그래피와 여러 컴포넌트에서 유용하게 쓰일 CSS 클래스들의 집합을 만들어 봅시다.
styles/utils.module.css
파일을 생성하고 아래의 코드를 넣어 주세요.
.heading2Xl {
font-size: 2.5rem;
line-height: 1.2;
font-weight: 800;
letter-spacing: -0.05rem;
margin: 1rem 0;
}
.headingXl {
font-size: 2rem;
line-height: 1.3;
font-weight: 800;
letter-spacing: -0.05rem;
margin: 1rem 0;
}
.headingLg {
font-size: 1.5rem;
line-height: 1.4;
margin: 1rem 0;
}
.headingMd {
font-size: 1.2rem;
line-height: 1.5;
}
.borderCircle {
border-radius: 9999px;
}
.colorInherit {
color: inherit;
}
.padding1px {
padding-top: 1px;
}
.list {
list-style: none;
padding: 0;
margin: 0;
}
.listItem {
margin: 0 0 1.25rem;
}
.lightText {
color: #666;
}
components/layout.js
세 번째로, components/layout.js
를 아래의 코드로 덮어 씌운 다음 Your Name
을 당신의 이름으로 변경해 주세요.
import Head from 'next/head'
import Image from 'next/image'
import styles from './layout.module.css'
import utilStyles from '../styles/utils.module.css'
import Link from 'next/link'
const name = 'Your Name'
export const siteTitle = 'Next.js Sample Website'
export default function Layout({ children, home }) {
return (
<div className={styles.container}>
<Head>
<link rel="icon" href="/favicon.ico" />
<meta
name="description"
content="Learn how to build a personal website using Next.js"
/>
<meta
property="og:image"
content={`https://og-image.vercel.app/${encodeURI(
siteTitle
)}.png?theme=light&md=0&fontSize=75px&images=https%3A%2F%2Fassets.vercel.com%2Fimage%2Fupload%2Ffront%2Fassets%2Fdesign%2Fnextjs-black-logo.svg`}
/>
<meta name="og:title" content={siteTitle} />
<meta name="twitter:card" content="summary_large_image" />
</Head>
<header className={styles.header}>
{home ? (
<>
<Image
priority
src="/images/profile.jpg"
className={utilStyles.borderCircle}
height={144}
width={144}
alt={name}
/>
<h1 className={utilStyles.heading2Xl}>{name}</h1>
</>
) : (
<>
<Link href="/">
<a>
<Image
priority
src="/images/profile.jpg"
className={utilStyles.borderCircle}
height={108}
width={108}
alt={name}
/>
</a>
</Link>
<h2 className={utilStyles.headingLg}>
<Link href="/">
<a className={utilStyles.colorInherit}>{name}</a>
</Link>
</h2>
</>
)}
</header>
<main>{children}</main>
{!home && (
<div className={styles.backToHome}>
<Link href="/">
<a>← Back to home</a>
</Link>
</div>
)}
</div>
)
}
뭐가 새로 생긴 걸까요?
og:image
와 같은 meta
태그들home
이라는 prop은 타이틀과 이미지 사이즈를 조정하는 데에 사용됩니다.home
이 false
라면 "Back to home" 링크는 하단에 위치합니다.next/image
로 추가된 이미지는 priority 속성 덕에 사전에 로드됩니다.pages/index.js
마지막으로, 메인 페이지를 수정해 봅시다.
pages/index.js
파일을 열고 아래의 코드를 덮어 씌워 주세요.
import Head from 'next/head'
import Layout, { siteTitle } from '../components/layout'
import utilStyles from '../styles/utils.module.css'
export default function Home() {
return (
<Layout home>
<Head>
<title>{siteTitle}</title>
</Head>
<section className={utilStyles.headingMd}>
<p>[Your Self Introduction]</p>
<p>
(This is a sample website - you’ll be building a site like this on{' '}
<a href="https://nextjs.org/learn">our Next.js tutorial</a>.)
</p>
</section>
</Layout>
)
}
[Your Self Introduction]
라는 텍스트를 여러분의 소개로 바꿔 주세요. 예시를 보여 드리죠.
끝이에요! 이제 우린 데이터 가져오기 레슨으로 넘어가기 위한 정돈된 레이아웃 코드를 갖추게 되었어요.
과정을 마무리하기 전에, 다음 페이지에서 Next.js의 CSS 내장 기능과 관련된 유용한 기술 몇 가지를 얘기해 볼게요.
스타일링에 대한 몇 가지 유용한 팁입니다.
이 섹션은 읽고만 넘어가도 괜찮습니다. 실습 중인 앱을 변경할 필요 없어요!
classnames
library to toggle classesclassnames
는 간단히 클래스명 토글을 구현해 주는 라이브러리입니다. npm install classnames
혹은 yarn add classnames
라는 명령어로 설치하면 됩니다.
기본적인 사용법은 이곳에서 보면 되지만, 자세한 내용은 이 문서를 참고하세요.
sucess
나 error
가 될 수 있는 type
값을 갖는 Alert
컴포넌트를 만들고 싶어 한다고 가정해 봅시다.success
일 때는 텍스트 색상을 초록색으로, error
일 때는 빨간색으로 변경하길 원합니다.먼저 CSS 묘듈(e.g. alert.module.css
)에 해당 코드를 작성합니다.
.success {
color: green;
}
.error {
color: red;
}
그리고 classnames
는 아래와 같이 사용합니다.
import styles from './alert.module.css'
import cn from 'classnames'
export default function Alert({ children, type }) {
return (
<div
className={cn({
[styles.success]: type === 'success',
[styles.error]: type === 'error'
})}
>
{children}
</div>
)
}
Next.js는 PostCSS를 사용하여 configuration 없이 CSS를 컴파일합니다.
PostCSS config를 커스텀하기 위해선 상위 레벨에 postcss.config.js
라는 파일을 생성해야 합니다. 이건 Tailwind CSS 라이브러리를 사용하는 경우에도 유용합니다.
아래는 Tailwind CSS를 추가하는 방법이니다. 먼저 패키지를 설치해 주세요.
npm install -D tailwindcss autoprefixer postcss
그리고, postcss.config.js
파일을 생성합니다.
// postcss.config.js
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {}
}
}
tailwind.config.js
의 content
옵션에 configuring content sources를 명시할 것을 추천합니다.
// tailwind.config.js
module.exports = {
content: [
'./pages/**/*.{js,ts,jsx,tsx}',
'./components/**/*.{js,ts,jsx,tsx}'
// For the best performance and to avoid false positives,
// be as specific as possible with your content configuration.
]
}
Next.js에서는 .scss
와 .sass
확장자의 Sass 파일이 import 가능합니다. CSS Modules와 .module.scss
혹은 .module.sass
확장자 파일을 통해 컴포넌트 레벨의 Sass를 사용할 수 있습니다.
Next.js의 Sass 내장 지원 기능을 사용하기 이전에, sass
를 꼭 설치해 주세요.
npm install -D sass