Nextjs를 사용한 프로젝트를 생성 중, 아이폰 15 프로 크기에 맞춰 개발하기 위한 전역 스타일링 설정이 필요해서 찾아보다가 정리하는 글 (
📁 styles
>globals.css
)
Next.js 12 이상에서 app
폴더를 사용할 경우, app
폴더 내 _app.js
파일을 생성하여 전체 애플리케이션에 대한 커스텀 App 컴포넌트를 정의한다는 사실을 알게 되었다.
폴더 및 파일의 전체적인 구조는 다음과 같다.
my-nextjs-project/
├─ app/
│ ├─ _app.js
│ ├─ (다른 컴포넌트 및 페이지)
├─ styles/
│ ├─ globals.css
├─ public/
│ ├─ ...
_app.js
파일 생성app
폴더의 루트에 _app.js
파일을 생성 후에는 다음과 같이 정의 해준다.
// app/_app.js
import '../styles/globals.css';
function MyApp({ Component, pageProps }) {
return <Component {...pageProps} />;
}
export default MyApp;
여기서 MyApp
함수는 두 가지 주요 목적을 갖는다.
1️⃣ 페이지 초기화: 모든 페이지 요청에 대해 실행되며, 페이지 컴포넌트와 페이지 프로퍼티(`pageProps`)를 렌더링한다.
2️⃣ 전역 상태 및 스타일 관리: 전역 CSS, 상태 관리 등을 설정하여 애플리케이션의 모든 페이지에 적용한다.
Component
: 현재 라우트에 해당하는 페이지 컴포넌트로, 페이지의 주요 내용을 구성한다.pageProps
: 서버 사이드 렌더링이나 정적 생성을 통해 미리 가져온 페이지의 props로, 이를 통해 각 페이지는 필요한 데이터를 사전에 로드하여 렌더링할 수 있다.또한 _app.js
에서 이 두 prop를 사용하여 모든 페이지에 공통적으로 적용되어야 하는 레이아웃, 스타일, 상태 관리 등을 처리할 수 있다.
예를 들어, 모든 페이지에 공통적인 헤더나 푸터, 사이드바를 추가하거나 전역 상태 관리 라이브러리를 연결할 수 있다.
// 헤더와 푸더 추가 예시
// _app.js
function MyApp({ Component, pageProps }) {
return (
<>
<Header /> {/* 모든 페이지에 공통 헤더 */}
<Component {...pageProps} /> {/* 현재 페이지 컴포넌트와 그 props를 렌더링 */}
<Footer /> {/* 모든 페이지에 공통 푸터 */}
</>
);
}
export default MyApp;
Next.js 프로젝트 내 CSS 대신 styled-components를 적용시키려고 했더니, 서버 사이드 렌더링을 위해 추가로 설정해야하는 것들이 있어서 정리한다.
babel-plugin-styled-components
설치yarn add babel-plugin-styled-components
.babelrc
파일 추가{
"presets": ["next/babel"],
"plugins": [["styled-components", { "ssr": true, "displayName": true }]]
}
styles
디렉토리 내 GlobalStyle.js
파일 생성
// styles/GlobalStyle.js
import { createGloablStyle } from 'styled-components';
const GlobalStyle = createGlobalStyle`
body {
margin: 0;
padding: 0;
box-sizing: border-box;
}
/* iPhone 15 Pro의 화면 크기에 맞는 스타일 */
@media only screen and (min-device-width: 390px) and (max-device-width: 844px) {
body {
width: 390px;
margin: 0 auto;
}
}
`;
export default GlobalStyle;
@media
미디어 쿼리를 사용하여 iPhone 15 Pro 의 화면 크기에 맞는 조건에서만 특정 스타일을 적용 (width: 390px; margin: 0 auto;
)390px X 844px
로 설정_app.js
파일에서 GlobalStyle
컴포넌트 임포트하고 애플리케이션의 최상위에 적용하기
// pages/_app.js 또는 app/_app.js
import GlobalStyle from '../styles/GlobalStyle';
function MyApp({ Component, pageProps }) {
return (
<>
<GlobalStyle />
<Component {...pageProps} />
</>
);
}
export default MyApp;
위와 같이 설정해주고 난 뒤 서버를 켜보니 이런 오류가 떴다.
찾아보니, nextjs는 13 버전 이후로 서버
와 클라이언트
컴포넌트가 각각 구분되기 때문에 발생하는 오류인 것으로 나타났다.
즉, Next.js 13 이상에서 styled-components
를 사용하려고 했더니 클라이언트 사이드에서만 처리되어야 하는 styled-components
가 서버 사이드에서 실행되었기 때문에 발생한 오류인 것이다.
use client
파일 내에 use client
지시어를 사용하면 컴포넌트를 클라이언트 컴포넌트로 명시적으로 변환해주기 때문에 컴포넌트 파일의 최상단에 추가해주면 오류가 해결된다.
하지만 그럼 컴포넌트 파일이 전부 클라이언트 컴포넌트로 변환되기 때문에 의도와는 다르게 설정이 된다는 문제가 발생한다.
그래서 styled 파일을 별도로 추가해서 style 파일에만 use client
지시어를 적용시키기로 했다.
login.style.js
) use client
지시어 사용page.js
) 파일에서 style 파일 임포트// login.style.js
"use client";
import styled from 'styled-components';
export const LoginContainer = styled.div`
border: 1px solid black;
`;
export const LoginBox = styled.div`
border: 1px solid blue;
`;
// page.js
import * as S from "./login.style";
export default function Login() {
return (
<S.LoginContainer>
<S.LoginBox>Another content</S.LoginBox>
</S.LoginContainer>
);
}