๐Ÿ’ป์šฉ๋‡ฝ ๊ฐœ๋ฐœ ๋…ธํŠธ๐Ÿ’ป
article thumbnail
๋ฐ˜์‘ํ˜•

Next.js + Typescript ์นด์นด์˜คํ†ก ๊ณต์œ ํ•˜๊ธฐ ๊ธฐ๋Šฅ ๊ตฌํ˜„

๐Ÿ“– ๋“ค์–ด๊ฐ€๋ฉฐ


์ด ํฌ์ŠคํŒ…์€ Next.js 11 ๋ฒ„์ „(page router) ํ™˜๊ฒฝ์—์„œ ์ž‘์„ฑ๋œ ๊ธ€์ž…๋‹ˆ๋‹ค.
13๋ฒ„์ „ ์ดํ›„ app router ํ™˜๊ฒฝ์—์„œ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ์ด ํฌ์ŠคํŒ…์—์„œ 1 ~ 1-3๊นŒ์ง€๋งŒ ๋ณด์‹œ๊ณ  ์—ฌ๊ธฐ๋ฅผ ์ฐธ๊ณ ํ•ด์ฃผ์„ธ์š”.

 

Next.js + Typescript ํ™˜๊ฒฝ์—์„œ ํ† ์ด ํ”„๋กœ์ ํŠธ๋ฅผ ์ง„ํ–‰ํ•˜๋˜ ์ค‘ ์นด์นด์˜คํ†ก์œผ๋กœ ๊ณต์œ ํ•˜๊ธฐ ๊ธฐ๋Šฅ์ด ํ•„์š”ํ•ด์„œ ๊ตฌํ˜„์„ ํ–ˆ์—ˆ๋Š”๋ฐ, ๋ช‡๋ช‡ ์˜ค๋ฅ˜๋„ ๋งˆ์ฃผ์น˜๊ณ  ๋”ฐ๋กœ ์ •๋ฆฌ๋ฅผ ํ•˜๋ฉด ์ข‹์„ ๊ฒƒ ๊ฐ™์•„์„œ ์ด๋ ‡๊ฒŒ ์ •๋ฆฌํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

1. ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋“ฑ๋กํ•˜๊ธฐ

์ผ๋‹จ ์ฒซ ๋ฒˆ์งธ๋กœ ๊ฐœ๋ฐœํ•˜๊ธฐ์— ์•ž์„œ์„œ Kakao Developers์—์„œ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋“ฑ๋ก์„ ํ•ด์ค˜์•ผ ํ•ฉ๋‹ˆ๋‹ค.

1-1 ๋กœ๊ทธ์ธ

์‚ฌ์ดํŠธ์— ์ ‘์† ํ•ด์ฃผ์‹œ๊ณ  ์ฒซ ํ™”๋ฉด์—์„œ ๋กœ๊ทธ์ธ์„ ํ•ด์ฃผ์‹œ๊ณ  '๋‚ด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜'์„ ํด๋ฆญํ•ด์ฃผ์„ธ์š”.

 

์นด์นด์˜ค ๋ฐ๋ธŒ ์ฒซํ™”๋ฉด

1-2 ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ถ”๊ฐ€ํ•˜๊ธฐ

๊ทธ๋Ÿฌ๋ฉด ์ด๋ ‡๊ฒŒ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋Š” ํ™”๋ฉด์ด ๋‚˜์˜ต๋‹ˆ๋‹ค.

์—ฌ๊ธฐ์„œ '์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ถ”๊ฐ€ํ•˜๊ธฐ'๋ฅผ ๋ˆŒ๋Ÿฌ์ฃผ์„ธ์š”.

๋‚ด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜

 

'์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ถ”๊ฐ€ํ•˜๊ธฐ'๋ฅผ ํด๋ฆญํ•˜๋ฉด ์ด๋ ‡๊ฒŒ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋Š” ๋ชจ๋‹ฌ ์ฐฝ์ด ๋‚˜์˜ต๋‹ˆ๋‹ค.

์•ฑ ์ด๋ฆ„์—๋Š” ๋งŒ๋“ค๊ณ ์ž ํ•˜๋Š” ์„œ๋น„์Šค ์ด๋ฆ„์„ ๊ธฐ์žฌํ•ด์ฃผ์‹œ๊ณ ,

์‚ฌ์—…์ž๋ช…์—๋Š” ์‚ฌ์—…์ž๋ช…์ด ์—†์œผ๋ฉด ๋ณธ์ธ ์ด๋ฆ„์„ ์ ์–ด์ฃผ์…”๋„ ๊ดœ์ฐฎ์Šต๋‹ˆ๋‹ค.

์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ถ”๊ฐ€ํ•˜๊ธฐ

 

์ถ”๊ฐ€๊ฐ€ ์™„๋ฃŒ ๋˜์—ˆ์œผ๋ฉด ํ•ด๋‹น ์ถ”๊ฐ€ํ•œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์š”์•ฝ์ •๋ณด์—๋Š” ๋ณธ์ธ์ด ์ƒ์„ฑํ•œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์•ฑ ํ‚ค๋“ค์ด ์กด์žฌํ•ฉ๋‹ˆ๋‹ค.

์—ฌ๊ธฐ์„œ ์ €ํฌ๋Š” JavaScript ํ‚ค๋ฅผ ์‚ฌ์šฉํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์š”์•ฝ ์ •๋ณด

 

1-3 Web ํ”Œ๋žซํผ ๋“ฑ๋ก

์ขŒ์ธก ๋ฉ”๋‰ด์—์„œ ํ”Œ๋žซํผ์ด๋ผ๋Š” ๋ฉ”๋‰ด๋ฅผ ํด๋ฆญํ•ด์ฃผ์‹œ๊ณ  ์ €ํฌ๊ฐ€ ์‚ฌ์šฉํ•  ์ฝ˜ํ…์ธ ๋Š” Web์ด๋‹ˆ๊น 'Web ํ”Œ๋žซํผ' ๋“ฑ๋ก ๋ฒ„ํŠผ์„ ํด๋ฆญํ•ด์ฃผ์‹œ๋ฉด ์•„๋ž˜์™€ ๊ฐ™์€ ํ™”๋ฉด์ด ๋‚˜์˜ค๋Š”๋ฐ, ์—ฌ๊ธฐ์„œ ์ €ํฌ๊ฐ€ ๊ฐœ๋ฐœํ™˜๊ฒฝ์—์„œ ์‚ฌ์šฉํ•  ์„œ๋ฒ„ ์ฃผ์†Œ์™€, ๋ฐฐํฌ๋ฅผ ํ•˜์…จ์œผ๋ฉด ๋ฐฐํฌํ•œ ์ฃผ์†Œ๋„ ๊ฐ™์ด ์ ์–ด์ฃผ์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค.

Webํ”Œ๋žซํผ ๋“ฑ๋ก

์ด์ œ ์นด์นด์˜คํ†ก ๊ณต์œ ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•  ์ค€๋น„๋‹จ๊ณ„๋Š” ๋๋‚ฌ์Šต๋‹ˆ๋‹ค.

2. ์ ์šฉ

2-1 JavaScript SDK ์ถ”๊ฐ€ํ•˜๊ธฐ

์ด์ œ ํ•ด๋‹น ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” SDK๋ฅผ ์ถ”๊ฐ€ํ•ด ์ค˜์•ผ ํ•ฉ๋‹ˆ๋‹ค.

 <script defer src="https://developers.kakao.com/sdk/js/kakao.min.js"></script>

์œ„์™€ ๊ฐ™์€ script ํƒœ๊ทธ๋ฅผ <head> ์‚ฌ์ด์— ์ž‘์„ฑํ•ด ์ค˜์•ผ ํ•˜๋Š”๋ฐ,

next.js์—์„œ๋Š” _documnet์—์„œ ๊ณตํ†ต์ ์œผ๋กœ ์‚ฌ์šฉํ•  <head> ๋˜๋Š” <body> ํƒœ๊ทธ ๋“ฑ ์•ˆ์— ๋“ค์–ด๊ฐˆ ๋‚ด์šฉ๋“ค์„ ์ปค์Šคํ…€ํ•  ๋•Œ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ด์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์€ ๊ณต์‹๋ฌธ์„œ๋ฅผ ์ฐธ๊ณ ํ•ด์ฃผ์„ธ์š”.

https://nextjs.org/docs/advanced-features/custom-document

 

Advanced Features: Custom `Document` | Next.js

Extend the default document markup added by Next.js.

nextjs.org

๊ทธ๋Ÿผ ์นด์นด์˜คํ†ก ๊ณต์œ  ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•  ํ”„๋กœ์ ํŠธ์— ๊ตฌ์„ฑ์„ ํ•ด์ฃผ๋„๋ก ํ•ฉ์‹œ๋‹ค.

'./pages/_document.tsx'

import Document, { Html, Head, Main, NextScript } from 'next/document';

class MyDocument extends Document {
  render() {
    return (
      <Html>
        <Head>
         <script
            defer
            src="https://developers.kakao.com/sdk/js/kakao.min.js"
          ></script>
        <Head/>
        <body>
          <Main />
          <NextScript />
        </body>
      </Html>
    );
  }
}

export default MyDocument;

2-2 env

์ฒ˜์Œ์—  Kakao Developers์—์„œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ถ”๊ฐ€ํ•˜๊ณ  ์š”์•ฝ ํƒญ์—์„œ ๋ดค๋˜ JavaScript ํ‚ค๋ฅผ envํŒŒ์ผ๋กœ ์ž‘์„ฑํ•ด์ค์‹œ๋‹ค.

API Key๋Š” ์ฝ”๋“œ์— ์ง์ ‘ ๋ช…์‹œํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค ๋ณด์•ˆ์ƒ envํŒŒ์ผ๋กœ ์ž‘์„ฑํ•ด ๋‘๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

๋ฃจํŠธ ํด๋”์— .env ํŒŒ์ผ์„ ์ƒ์„ฑํ•˜๊ณ  ์•„๋ž˜์™€ ๊ฐ™์ด ์ž‘์„ฑํ•ด์ฃผ์„ธ์š”. 

(API ํ‚ค๋ฅผ ์ž‘์„ฑํ•  ๋•Œ ' ' ๋”ฐ์˜ดํ‘œ๋Š” ํ•„์š” ์—†์Šต๋‹ˆ๋‹ค.)

'.env'

NEXT_PUBLIC_KAKAO_API_KEY=APIํ‚ค

2-3 initialize

์ด์ œ JavaScript ํ‚ค๋ฅผ ์ด์šฉํ•ด์„œ initialize๋ฅผ ํ•ด์ค˜์•ผ ํ•ฉ๋‹ˆ๋‹ค.

initialize๋Š” ์•„๋ž˜์™€ ๊ฐ™์ด ํ•ด์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ƒ์œ„ ์ปดํฌ๋„ŒํŠธ (ex. Layout or _app)์—์„œ ๋งˆ์šดํŠธ ๋  ๋•Œ ์ ์šฉ๋  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์ค์‹œ๋‹ค.

ํ•˜๋‚˜์˜ ํŽ˜์ด์ง€์—์„œ๋งŒ ๊ณต์œ  ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•  ๊ฒƒ์ด๋ผ๋ฉด ์‚ฌ์šฉํ•  ํŽ˜์ด์ง€์—์„œ ์ž‘์„ฑํ•ด๋„ ๋ฉ๋‹ˆ๋‹ค.

์ €๋Š” ์—ฌ๋Ÿฌ ํŽ˜์ด์ง€์—์„œ ์‚ฌ์šฉ์„ ํ•˜๊ธฐ ์œ„ํ•ด์„œ ์ƒ์œ„ ์ปดํฌ๋„ŒํŠธ(Layout.tsx)์— ์ž‘์„ฑํ•ด์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค.

ex)

'./src/components/common/Layout.tsx'

import GlobalStyle from 'styles/GlobalStyle';
import styled from 'styled-components';
import { size } from 'styles/theme';
import Footer from './Footer';
import DarkModeBtn from '../Buttons/DarkModeBtn';
import { useEffect } from 'react';

const Wrapper = styled.div`
  width: 100%;
  max-width: ${size.mobile};
  min-height: 100vh;
  margin: auto;
  padding: ${({ theme }) => theme.padding.base};
  display: flex;
  flex-direction: column;
  justify-content: center;
`;

interface IProps {
  children: React.ReactNode;
}

const Layout = ({ children }: IProps) => {
  useEffect(() => {
      window.Kakao.init(process.env.NEXT_PUBLIC_KAKAO_API_KEY);
  }, []);

  return (
    <Wrapper>
      <GlobalStyle />
      <DarkModeBtn />
      {children}
      <Footer />
    </Wrapper>
  );
};

export default Layout;

๊ทธ๋ฆฌ๊ณ  ์ด๋ ‡๊ฒŒ๋งŒ ์ž‘์„ฑํ•˜๊ฒŒ ๋˜๋ฉด window ๊ฐ์ฒด ์•ˆ์— Kakao๊ฐ€ ์—†๋‹ค๊ณ  ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

window ๊ฐ์ฒด์— Kakao๊ฐ€ ์žˆ๋‹ค๊ณ  ์•Œ๋ ค์ค˜์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์ „์—ญ์œผ๋กœ window interface๋ฅผ ์ •์˜ํ•ด์ค์‹œ๋‹ค.

'./pages/_app.tsx'

import type { AppProps } from 'next/app';
import Layout from 'src/components/common/Layout';
import ThemeProvider from 'src/context/ThemeProvider';

declare global {
  interface Window {
    Kakao: any;
  }
}

function MyApp({ Component, pageProps }: AppProps) {
  return (
    <ThemeProvider>
      <Layout>
        <Component {...pageProps} />
      </Layout>
    </ThemeProvider>
  );
}
export default MyApp;

TypeScript์—์„œ any ํƒ€์ž…์„ ์ตœ๋Œ€ํ•œ ์ง€ํ–ฅํ•˜๋Š” ๊ฒƒ์ด ์ข‹์ง€๋งŒ, Kakao์˜ type์„ ๋”ฐ๋กœ ์•Œ ์ˆ˜ ์—†์–ด์„œ any๋กœ ๋ช…์‹œํ–ˆ์Šต๋‹ˆ๋‹ค.

์ด๋ ‡๊ฒŒ ๋ช…์‹œ๋ฅผ ํ•ด์ฃผ๋ฉด ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š๊ณ  window ๊ฐ์ฒด์˜ Kakao์— ์ ‘๊ทผ์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

2-4 onClick function

์ €๋Š” ์นด์นด์˜ค ๊ณต์œ  ๊ธฐ๋Šฅ์„ ํ•˜๋Š” ๋ฒ„ํŠผ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋”ฐ๋กœ ์ž‘์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค.

import Button from '../common/Button';
import styled from 'styled-components';
import KakaoIcon from 'public/images/kakaotalk_logo_icon_147272.svg';

const SButton = styled(Button)`
  display: flex;
  justify-content: center;
  align-items: center;
`;

const KakaoBtn = () => {
  const onClick = () => {
    const { Kakao, location } = window;
    Kakao.Link.sendScrap({
      requestUrl: location.href,
    });
  };
  return (
    <SButton fontColor="yellow" borderColor="whiteYellow" onClick={onClick}>
      <KakaoIcon viewBox="0 0 60 48" width="30px" height="23px" />
      ์นด์นด์˜คํ†ก ๊ณต์œ ํ•˜๊ธฐ
    </SButton>
  );
};

export default KakaoBtn;

๋ฒ„ํŠผ์„ ํด๋ฆญํ–ˆ์„ ๋•Œ ์‹คํ–‰ํ•˜๋Š” onClick ํ•จ์ˆ˜์—์„œ ๊ธฐ๋Šฅ์„ ํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด ์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค.

์•„๋ž˜์™€ ๊ฐ™์€ ๋ถ€๋ถ„์€ requestUrl์ด ๊ณต์œ ํ•  Url์ž…๋‹ˆ๋‹ค.

location.href๋ฅผ ์ž‘์„ฑํ•ด ์คŒ์œผ๋กœ์จ ํ˜„์žฌ ์œ„์น˜ํ•ด์žˆ๋Š” URL์„ ๊ณต์œ ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ–ˆ์Šต๋‹ˆ๋‹ค.

 Kakao.Link.sendScrap({
      requestUrl: location.href,
    });

๊ทธ๋ฆฌ๊ณ  ์ค‘์š”ํ•œ ๋ถ€๋ถ„์€ ์นด์นด์˜ค ๊ณต์œ  ๋ฐฉ์‹์— ์žˆ์–ด์„œ ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๋‹ค.

ex)

์‚ฌ์šฉ์ž ์ •์˜ ํ…œํ”Œ๋ฆฟ

https://developers.kakao.com/docs/latest/ko/message/js-link

 

Kakao Developers

์นด์นด์˜ค API๋ฅผ ํ™œ์šฉํ•˜์—ฌ ๋‹ค์–‘ํ•œ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๊ฐœ๋ฐœํ•ด๋ณด์„ธ์š”. ์นด์นด์˜ค ๋กœ๊ทธ์ธ, ๋ฉ”์‹œ์ง€ ๋ณด๋‚ด๊ธฐ, ์นœ๊ตฌ API, ์ธ๊ณต์ง€๋Šฅ API ๋“ฑ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

developers.kakao.com

์ €๋Š” SEO๋ฅผ ์œ„ํ•ด ํŽ˜์ด์ง€์— meta og tag๋ฅผ ์ž‘์„ฑํ•ด์„œ ๊ณต์‹๋ฌธ์„œ(์œ„์— ๋งํฌ)๋ฅผ ์ฐธ๊ณ ํ•ด์„œ ์Šคํฌ๋žฉํ•œ ์›น ํŽ˜์ด์ง€ ์ •๋ณด๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ ๋ฉ”์‹œ์ง€ ๋‚ด์šฉ์„ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ๋„๋ก Kakao.Link.sendScrap ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค.

์œ„ ๋งํฌ๋ฅผ ์ฐธ๊ณ ํ•ด ๋ณด์‹œ๋ฉด ์ง์ ‘ ๋ฉ”์„ธ์ง€ ์ œ๋ชฉ, ๋‚ด์šฉ ๋“ฑ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ๋Š” ๋ฉ”์„œ๋“œ๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

์ €๋Š” ๋งŽ์€ ๊ฒƒ๋“ค ์ค‘ sendScrap๋ฅผ ์‚ฌ์šฉํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ  ๋งŒ์•ฝ ๊ฐœ๋ฐœ ํ™˜๊ฒฝ(localhost) ํ™˜๊ฒฝ์—์„œ sendScrap๋ฅผ ํ†ตํ•œ ๊ณต์œ  ๊ธฐ๋Šฅ์„ ํ…Œ์ŠคํŠธํ•  ์‹œ ์นด์นด์˜ค์—์„œ locahost:3000 ์ฃผ์†Œ๋ฅผ ์Šคํฌ๋žฉํ•  ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์— ์ œ๋ชฉ, ๋‚ด์šฉ ๋“ฑ ์ œ๋Œ€๋กœ ํ‘œ์‹œ๊ฐ€ ๋˜์ง€ ์•Š๋Š” ๊ฒŒ ์ •์ƒ์ž…๋‹ˆ๋‹ค.

๋ณ„๋‹ค๋ฅธ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด ํ”„๋กœ์ ํŠธ๋ฅผ ๋ฐฐํฌํ•œ ์ฃผ์†Œ์—์„œ ํ…Œ์ŠคํŠธ๋ฅผ ํ•ด๋ณด์‹œ๋ฉด ์ •์ƒ์ ์œผ๋กœ ๋ฉ”์‹œ์ง€ ๋‚ด์šฉ์ด ๋‚˜ํƒ€๋‚˜๋Š” ๊ฑธ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๐Ÿ“• ๋งˆ๋ฌด๋ฆฌ

Next.js + TypeScript ํ™˜๊ฒฝ์—์„œ ์นด์นด์˜คํ†ก์œผ๋กœ ๊ณต์œ ํ•˜๊ธฐ ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด์„œ ์•Œ์•„๋ดค์Šต๋‹ˆ๋‹ค.

ํ˜น์‹œ ์ดํ•ด๊ฐ€ ์•ˆ ๋˜์‹œ๊ฑฐ๋‚˜ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐ์— ์žˆ์–ด์„œ ๋ชจ๋ฅด์‹œ๋Š” ๋ถ€๋ถ„์ด ์žˆ์œผ์‹œ๋ฉด ๋Œ“๊ธ€ ๋‚จ๊ฒจ์ฃผ์„ธ์š”!

๋ฐ˜์‘ํ˜•
profile

๐Ÿ’ป์šฉ๋‡ฝ ๊ฐœ๋ฐœ ๋…ธํŠธ๐Ÿ’ป

@์šฉ๋‡ฝ

ํฌ์ŠคํŒ…์ด ์ข‹์•˜๋‹ค๋ฉด "์ข‹์•„์š”โค๏ธ" ๋˜๋Š” "๊ตฌ๋…๐Ÿ‘๐Ÿป" ํ•ด์ฃผ์„ธ์š”!