๐ŸŽ Gift MBTI - 2. Result ํŽ˜์ด์ง€ ์‹œ์ž‘(Emotion theme ์ ์šฉ, SEO ์ตœ์ ํ™” )

zamanยท2022๋…„ 9์›” 27์ผ
0

Toy Projects

๋ชฉ๋ก ๋ณด๊ธฐ
2/6
post-thumbnail

Emotion

์ด๋ฒˆ ํ”„๋กœ์ ํŠธ์—์„  emotion์œผ๋กœ ์Šคํƒ€์ผ๋ง์„ ํ•˜๊ธฐ๋กœ ํ–ˆ๋Š”๋ฐ ํŠน๋ณ„ํ•œ ์ด์œ ๊ฐ€ ์žˆ๋˜ ๊ฒƒ์€ ์•„๋‹ˆ๊ณ  ๊ทธ๋ƒฅ ๋‹ค๋“ค ๋งŽ์ด ์“ฐ๊ธธ๋ž˜ ์‚ฌ์šฉํ•ด๋ดค๋‹ค.
ํ•œ ๋ฒˆ๋„ ์‚ฌ์šฉํ•ด๋ณธ์  ์—†๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ผ ๊ฑฑ์ •ํ–ˆ๋Š”๋ฐ ์›ฌ๊ฑธ ๊ทธ๋ƒฅ ๋ฌธ๋ฒ•์ด styled-components๋ž‘ ๋˜‘๊ฐ™์•˜๋‹ค!

์ฐพ์•„๋ณด๋‹ˆ ๋‘˜ ๋‹ค CSS-in-JS์— sass ๋ฌธ๋ฒ•์„ ์‚ฌ์šฉํ•ด์„œ ์ฐจ์ด๋ฅผ ๋ชป๋Š๊ผˆ๋˜ ๊ฒƒ์ด๋‹ค.

CSS-in-JS
: JS ์•ˆ์—์„œ css์ฝ”๋“œ๋ฅผ ๊ด€๋ฆฌ
css ์ฝ”๋“œ๋ฅผ ๋ณ€์ˆ˜๋กœ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ๋™์ ์œผ๋กœ css ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๊ธฐ ์‰ฝ๋‹ค๋Š” ์žฅ์ ์ด ์žˆ์Œ

emotion์ด styled-components๋ณด๋‹ค ์กฐ๊ธˆ ๋” ๊ฐ€๋ณ๊ณ  ๋น ๋ฅด๋‹ค๊ณ  ํ•œ๋‹ค. ๊ทธ๋ฆฌ๊ณ  SSR์—์„œ emotion์€ ๋ณ„๋„ ์„ค์ • ์—†์ด ๋™์ž‘ํ•˜์ง€๋งŒ Styled-components๋Š” ServerStyleSheet ์„ค์ •์„ ํ•ด์•ผํ•œ๋‹ค๊ณ  ํ•œ๋‹ค.

์ฐธ์กฐ ๋ธ”๋กœ๊ทธ: https://intrepidgeeks.com/tutorial/whats-the-difference-between-a-styled-component-and-emotion

๊ทธ๋Ÿผ emotion์ด ๋ญ”์ง€๋„ ์•Œ์•„๋ดค์œผ๋‹ˆ ์ด์ œ ์‚ฌ์šฉํ•ด๋ณด๋„๋ก ํ•˜์ž

1. emotion ์„ค์น˜ํ•˜๊ธฐ

yarn๋‚˜ npm ์ค‘ ํŽธํ•œ๊ฑธ๋กœ ๊ณจ๋ผ์“ฐ๋ฉด ๋œ๋‹ค. ๋‹จ ํ˜ผ์šฉ์€ ํ”ผํ•˜์ž!

yarn add @emotion/react
yarn add @emotion/styled
๋˜๋Š”
npm install --save @emotion/react
npm install --save @emotion/styled

2. Emotion theme ์„ค์ •ํ•˜๊ธฐ

ํ…Œ๋งˆ ์„ค์ •๋„ ๊ฐ„๋‹จํ•˜๋‹ค
๋จผ์ € TypeScript๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์œผ๋ฏ€๋กœ emotion.d.ts์—์„œ ํ•„์š”ํ•œ ์ƒ‰๊ณผ ํฐํŠธ ํƒ€์ž…์„ ์ง€์ •ํ•œ๋‹ค.

import '@emotion/react';

declare module '@emotion/react' {
  export interface Theme {
    color: {
      purple: string;
      // ...
      skyblue: string;
    };
    
    font: { main: string };
  }
}

์ตœ์ƒ์œ„ ํŒŒ์ผ _app.tsx์—์„œ ThemeProvider๋ฅผ ์ ์šฉ์‹œ์ผœ์ค€๋‹ค.
์ด๋ ‡๊ฒŒ ํ•ด์•ผ ํ•˜์œ„ ์ปดํฌ๋„ŒํŠธ๋“ค์ด ํ…Œ๋งˆ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค. โ†’ css prop

reset.ts์—์„œ html ๊ธฐ๋ณธ ์Šคํƒ€์ผ์„ ์—†์• ๊ณ  ์ƒˆ๋กœ์šด ์Šคํƒ€์ผ์„ ๊ธ€๋กœ๋ฒŒ ์Šคํƒ€์ผ๋กœ ์ ์šฉํ–ˆ๋‹ค.

import type { AppProps } from 'next/app';
import { css, Global, ThemeProvider } from '@emotion/react';
import reset from '../styles/reset';
import theme from '../styles/themes';

const MyApp = ({ Component, pageProps }: AppProps) => {
  return (
    <ThemeProvider theme={theme}>
      <Global
        styles={css`
          ${reset}
        `}
      />
      <Component {...pageProps} />
    </ThemeProvider>
  );
};

export default MyApp;

๊ทธ๋ฆฌ๊ณ  theme.tsx ์—์„œ ์ƒ์„ธ ์ƒ‰๊ณผ ํฐํŠธ ๊ฐ’์„ ์ง€์ •ํ•œ๋‹ค

import { Theme } from '@emotion/react';

const color = {
  purple: '#9268EC',
  // ...
  skyblue: '#93D8FF',
};
const font = { main: 'Pretendard' };

const theme: Theme = {
  color: {
    purple: color.purple,
    // ...
    skyblue: color.skyblue,
  },
  font: { main: font.main },
};

export default theme;

์ด์ œ ์›ํ•˜๋Š” ์žฅ์†Œ์—์„œ ์‚ฌ์šฉํ•˜๋ฉด ๋

์‚ฌ์šฉ์€ ์ด๋Ÿฐ์‹์œผ๋กœ!
color: ${(props) => props.theme.color.skyblue};



SEO

์ฒซ SSR ํ”„๋กœ์ ํŠธ๋‹ค๋ณด๋‹ˆ SEO์— ์‹ ๊ฒฝ์„ ๋งŽ์ด ์“ฐ๊ณ  ์‹ถ์—ˆ๋‹ค. ๋˜ ์—ด์‹ฌํžˆ ๋งŒ๋“ค ํ”Œ์ ์ด ๋ฌปํžˆ๋ฉด ์•„์‰ฌ์šฐ๋‹ˆ๊นŒใ…Žใ…Ž

๊ฒ€์ƒ‰์—”์ง„์ตœ์ ํ™”(SEO)
: ๊ฒ€์ƒ‰์—”์ง„์ด ์ž๋ฃŒ๋ฅผ ์ˆ˜์ง‘ํ•˜๊ณ  ์ˆœ์œ„๋ฅผ ๋งค๊ธธ ๋•Œ ํƒœ๊ทธ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ๊ฒ€์ƒ‰ ํ‚ค์›Œ๋“œ ์šฐ์„ ์ˆœ์œ„๋ฅผ ํŒŒ์•…ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ชฉ์ ์— ๋ถ€ํ•ฉํ•œ ํƒœ๊ทธ๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ ๋…ธ์ถœ์— ์œ ๋ฆฌ (Div์—์„œ ๋ฒ—์–ด๋‚˜๊ธฐ)

ํฌ๋กฌ ๊ฐœ๋ฐœ์ž๋„๊ตฌ์˜ Lighthouse์˜ SEO 100์ ์„ ๋ชฉํ‘œ๋กœ ํƒญ ์ œ๋ชฉ๋ฅผ mbti type์— ๋”ฐ๋ผ ๋ณ€๊ฒฝํ•ด ๋ณด์•˜๋‹ค.

ํƒญ ์ œ๋ชฉ ๋ณ€๊ฒฝ์€ SEO์— ๋งž๊ฒŒ ์‚ฌ์ดํŠธ๋ฅผ ์ตœ์ ํ™”ํ•˜๋Š” ๋ฐฉ๋ฒ• ์ค‘ ํ•˜๋‚˜๊ธฐ๋„ ํ•˜๊ณ  ์—ฌ๋Ÿฌ ํƒญ์„ ์—ด์–ด๋‘์—ˆ์„ ๋•Œ ๋ธŒ๋ผ์šฐ์ € ํ‘œ์‹œ์ค„์—์„œ ๊ด€๋ จ ์‚ฌ์ดํŠธ๋ฅผ ๋น ๋ฅด๊ฒŒ ์‹๋ณ„ํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋œ๋‹ค.

ํƒญ ์ œ๋ชฉ์„ ๋ณ€๊ฒฝํ•˜๋Š” ๋ฐฉ๋ฒ•๋„ ์งฑ ๊ฐ„๋‹จํ•˜๋‹ค
seo.tsx

import Head from 'next/head';

interface IType {
  type: string;
}

const SEO = ({ type }: IType) => {
  return (
    <Head>
      <title> {type} | Gift MBTI</title>
    </Head>
  );
};

export default SEO;

import Head from 'next/head';์€ ์„œ๋ฒ„๋กœ ๋ถ€ํ„ฐ <head>ํƒœ๊ทธ๋ฅผ ๋ฐ›์•„ ์™€์ค€๋‹ค

Head์— ๋Œ€ํ•ด ๋” ๊ถ๊ธˆํ•˜๋‹ค๋ฉด ์•„๋ž˜ ๋ธ”๋กœ๊ทธ๋ฅผ ์ฐธ์กฐํ•ด๋ด๋„ ์ข‹์„ ๊ฒƒ ๊ฐ™๋‹ค!
https://velog.io/@cyranocoding/NEXT-HEAD-%EC%97%90-%EB%8C%80%ED%95%98%EC%97%AC

์‚ฌ์šฉํ•  ๋• ์›ํ•˜๋Š” ํŽ˜์ด์ง€์—์„œ importํ•ด ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค

 <SEO type={type} />




์ด๋ ‡๊ฒŒ ๊ธฐ๋ณธ ์„ค์ •์„ ํ•ด๋‘๊ณ  ์Šคํƒ€์ผ๋ง์„ ์ง„ํ–‰ํ–ˆ๋Š”๋ฐ ๋””์ž์ด๋„ˆ์™€ ํ˜‘์—…ํ•˜๋Š” ๋งŒํผ ์˜ˆ์œ ์›น์ด ์™„์„ฑ๋˜์ง€๋งŒ ๊ทธ๋งŒํผ ์Šคํƒ€์ผ๋ง๋„ ์–ด๋ ค์› ๋‹ค.
๊ทธ๋ž˜๋„ ์™„์„ฑ๋œ ํŽ˜์ด์ง€๋ฅผ ๋ณด๋ฉด ๋ฟŒ๋“ฏํ•˜๋‹คใ…Žใ…Ž
๋นจ๋ฆฌ ์™„์„ฑํ•ด์„œ ์นœ๊ตฌ๋“คํ•œํ…Œ ๋ฟŒ๋ฆฌ๊ณ  ์‹ถ๋‹ค!


profile
๊ฐœ๋ฐœ์ž๋กœ ์„ฑ์žฅํ•˜๊ธฐ ์œ„ํ•œ ์•„์นด์ด๋ธŒ ๐Ÿ˜Ž

0๊ฐœ์˜ ๋Œ“๊ธ€