framework/NextJS

๐ŸŽจ Next.js App Router์—์„œ CSS-in-JS ์‚ฌ์šฉํ•˜๊ธฐ

octo54 2025. 5. 9. 11:05
๋ฐ˜์‘ํ˜•

๐ŸŽจ Next.js App Router์—์„œ CSS-in-JS ์‚ฌ์šฉํ•˜๊ธฐ

Next.js App Router๋Š” ๋‹ค์–‘ํ•œ CSS-in-JS ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ง€์›ํ•˜์—ฌ, ์Šคํƒ€์ผ์„ ์ปดํฌ๋„ŒํŠธ ๋‚ด๋ถ€์—์„œ ์„ ์–ธํ•˜๊ณ  ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” ์žฅ์ ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
์ด ๊ฐ€์ด๋“œ์—์„œ๋Š” Next.js์—์„œ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ์ฃผ์š” CSS-in-JS ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์™€ ๊ฐ๊ฐ์˜ ์„ค์ • ๋ฐฉ๋ฒ•์„ ์†Œ๊ฐœํ•ฉ๋‹ˆ๋‹ค.


โœ… 1. CSS-in-JS์˜ ์žฅ์ 

  • ๋ชจ๋“ˆํ™”: ์ปดํฌ๋„ŒํŠธ ๋‹จ์œ„๋กœ ์Šคํƒ€์ผ์„ ๊ด€๋ฆฌํ•˜์—ฌ ์ถฉ๋Œ ๋ฐฉ์ง€
  • ๋™์  ์Šคํƒ€์ผ: ์ƒํƒœ ๊ธฐ๋ฐ˜์œผ๋กœ ์Šคํƒ€์ผ์„ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์Œ
  • ์ž์ฒด ํ˜ธ์ŠคํŒ…: Google Fonts ๋“ฑ์„ ์ง์ ‘ ํ˜ธ์ŠคํŒ… ๊ฐ€๋Šฅ
  • ์„œ๋ฒ„ ์‚ฌ์ด๋“œ ๋ Œ๋”๋ง(SSR): Next.js์™€ ์ž˜ ๋งž์•„ SEO ์„ฑ๋Šฅ ํ–ฅ์ƒ

โœ… 2. Styled Components ์‚ฌ์šฉํ•˜๊ธฐ

์„ค์น˜

npm install styled-components
npm install -D @types/styled-components

์„ค์ • ํŒŒ์ผ ์ถ”๊ฐ€

// app/layout.tsx
'use client';
import { ThemeProvider } from 'styled-components';

const theme = {
  colors: {
    primary: '#0070f3',
  },
};

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="ko">
      <body>
        <ThemeProvider theme={theme}>{children}</ThemeProvider>
      </body>
    </html>
  );
}

์‚ฌ์šฉ๋ฒ•

// app/page.tsx
'use client';
import styled from 'styled-components';

const Title = styled.h1`
  font-size: 2rem;
  color: ${(props) => props.theme.colors.primary};
`;

export default function HomePage() {
  return <Title>Styled Components ์ ์šฉ ์™„๋ฃŒ</Title>;
}

โœ… 3. Emotion ์‚ฌ์šฉํ•˜๊ธฐ

๋ฐ˜์‘ํ˜•

์„ค์น˜

npm install @emotion/react @emotion/styled
npm install -D @emotion/babel-plugin

์„ค์ • ํŒŒ์ผ (babel.config.js)

module.exports = {
  presets: ['next/babel'],
  plugins: ['@emotion/babel-plugin'],
};

์‚ฌ์šฉ๋ฒ•

// app/page.tsx
'use client';
import styled from '@emotion/styled';

const Title = styled.h1`
  font-size: 2rem;
  color: hotpink;
`;

export default function HomePage() {
  return <Title>Emotion์œผ๋กœ ์Šคํƒ€์ผ๋ง!</Title>;
}

โœ… 4. Stitches ์‚ฌ์šฉํ•˜๊ธฐ

์„ค์น˜

npm install @stitches/react

์‚ฌ์šฉ๋ฒ•

// app/page.tsx
'use client';
import { createStitches } from '@stitches/react';

const { styled } = createStitches({
  theme: {
    colors: {
      primary: 'blue',
    },
  },
});

const Title = styled('h1', {
  fontSize: '2rem',
  color: '$primary',
});

export default function HomePage() {
  return <Title>Stitches ์Šคํƒ€์ผ ์ ์šฉ</Title>;
}

โœ… 5. Vanilla Extract ์‚ฌ์šฉํ•˜๊ธฐ

์„ค์น˜

npm install @vanilla-extract/css
npm install -D @vanilla-extract/babel-plugin

์„ค์ • ํŒŒ์ผ (babel.config.js)

module.exports = {
  presets: ['next/babel'],
  plugins: ['@vanilla-extract/babel-plugin'],
};

์‚ฌ์šฉ๋ฒ•

// styles.css.ts
import { style } from '@vanilla-extract/css';

export const title = style({
  fontSize: '2rem',
  color: 'green',
});
// app/page.tsx
'use client';
import { title } from './styles.css';

export default function HomePage() {
  return <h1 className={title}>Vanilla Extract ์Šคํƒ€์ผ ์ ์šฉ</h1>;
}

โœ… 6. Linaria ์‚ฌ์šฉํ•˜๊ธฐ

์„ค์น˜

npm install @linaria/react @linaria/babel-preset

์„ค์ • ํŒŒ์ผ (babel.config.js)

module.exports = {
  presets: ['next/babel', '@linaria'],
};

์‚ฌ์šฉ๋ฒ•

// app/page.tsx
'use client';
import { css } from '@linaria/core';

const title = css`
  font-size: 2rem;
  color: darkorange;
`;

export default function HomePage() {
  return <h1 className={title}>Linaria ์Šคํƒ€์ผ ์ ์šฉ</h1>;
}

โœ… ์ฃผ์š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋น„๊ต

๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ํŠน์ง• SSR ์ง€์› ์—ฌ๋ถ€ ์ฃผ์š” ์žฅ์ 

Styled Components ๊ฐ€์žฅ ๋„๋ฆฌ ์‚ฌ์šฉ, ์Šคํƒ€์ผ ๋ชจ๋“ˆํ™” O ๊ฐ„๋‹จํ•œ ์„ค์ •๊ณผ ์ปดํฌ๋„ŒํŠธ ๊ธฐ๋ฐ˜ ์Šคํƒ€์ผ
Emotion ์„ฑ๋Šฅ ์šฐ์ˆ˜, ์œ ์—ฐ์„ฑ ๋†’์€ ์Šคํƒ€์ผ๋ง O ๋™์  ์Šคํƒ€์ผ ์ ์šฉ์— ์œ ๋ฆฌ
Stitches ๋น ๋ฅธ ์„ฑ๋Šฅ, ๊ฒฝ๋Ÿ‰ O ๋””์ž์ธ ์‹œ์Šคํ…œ ๊ตฌ์ถ•์— ์ ํ•ฉ
Vanilla Extract ํƒ€์ž… ์•ˆ์ „ CSS X ์ปดํŒŒ์ผ ํƒ€์ž„ ์Šคํƒ€์ผ ์ ์šฉ
Linaria Zero-runtime CSS-in-JS X ์„ฑ๋Šฅ ์ตœ์ ํ™”์™€ ๊ฐ„๋‹จํ•œ ์‚ฌ์šฉ๋ฒ•

โœ… ์š”์•ฝ

Next.js App Router์—์„œ๋Š” ๋‹ค์–‘ํ•œ CSS-in-JS ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ํ”„๋กœ์ ํŠธ ์š”๊ตฌ์‚ฌํ•ญ์— ๋”ฐ๋ผ ์ ํ•ฉํ•œ ๋„๊ตฌ๋ฅผ ์„ ํƒํ•˜๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค.
SSR ์ง€์› ์—ฌ๋ถ€์™€ ์„ฑ๋Šฅ, ์‚ฌ์šฉ์„ฑ์„ ๊ณ ๋ คํ•˜์—ฌ ์„ ํƒํ•˜๋Š” ๊ฒƒ์ด ๊ถŒ์žฅ๋ฉ๋‹ˆ๋‹ค.

 

Next.js, CSS-in-JS, Styled Components, Emotion, Stitches, Vanilla Extract, Linaria, ์Šคํƒ€์ผ๋ง, SSR ์ง€์›, ์„ฑ๋Šฅ ์ตœ์ ํ™”