오늘까지 구체적인 기획 회의를 마무리하고,
프로젝트 초기 세팅을 하고 본격적인 개발에 막 착수했다!
개발 환경
- next.js (page router)
- typescript
- tailwind CSS
- rtk
- react-query
우리는 웹 사이트가 노출되는 것이 중요하기 때문에 검색 엔진 최적화 (SEO) 가 가능한 next.js
를 사용했다. 그리고 지난 번에 처음 tailwind CSS
로 프로젝트를 진행해보았는데, 일단 next와 찰떡 궁합이고, 코드가 엄청 길어지지 않아서 간결하고, 이름을 따로 짓지 않아도 된다는 장점, 또 반응형 구현하기 쉽다는 장점 때문에 tailwind CSS
를 선택했다. 전역 상태 관리 라이브러리는 redux toolkit
을 사용하기로 하였고, 서버 상태 관리는 react-query
를 사용할 것이다.
공통적인 레이아웃을 적용하기 위해 Layout.tsx
컴포넌트를 만들고 _app.tsx
파일에 주입했다.
// src/components/Layout.tsx
import React, { ReactNode } from 'react';
import Header from './layout/Header';
import Footer from './layout/Footer';
type Props = {
children: ReactNode;
};
const Layout = ({ children }: Props) => {
return (
<div className='flex flex-col justify-between h-[100vh]'>
<div>
<Header />
{children}
</div>
<Footer />
</div>
);
};
export default Layout;
헤더와 푸터 컴포넌트를 만들고, 항상 푸터가 최하단에 위치했으면 좋겠는데,
처음에 헤더와 푸더 사이에 div
태그에 min-h-screen
과 같은 속성을 주는 방식을 사용했다가, 팀원분이 좀 더 획기적인 방법을 공유해주셨다.!!!
헤더와 푸터를 감싸는 div
태그에 'flex flex-col justify-between h-[100vh]'
이런 속성을 먹이는 것이다.!!
Layout.tsx 컴포넌트 (헤더 푸더) 를 회원가입과 로그인 페이지에는 적용하지 않고 싶었다. 이를 위한 다양한 방법이 있다.
next.js에서 _app.ts
파일은 모든 페이지에 대한 공통적인 레이아웃을 설정할 수 있는 특별한 파일이다. 이 파일에서 조건문을 활용하여 로그인 or 회원가입 페이지에는 레이아웃을 적용하지 않도록 할 수 있다.
그래서 다음과 같이 router.pathname 이 /login
또는 /signup
일 때는 Layout
을 제외하고 리턴할 수 있도록 했다.
// src/pages/_app.tsx
import '@/styles/globals.css';
import type { AppProps } from 'next/app';
import Providers from './providers';
import { useRouter } from 'next/router';
export default function App({ Component, pageProps }: AppProps) {
const router = useRouter();
if (router.pathname === '/login' || router.pathname === '/signup') {
return (
<Providers>
<Component {...pageProps} />
</Providers>
);
}
return (
<Providers>
<Layout>
<Component {...pageProps} />
</Layout>
</Providers>
);
}
나는 로그인 로그아웃 페이지만 Layout 컴포넌트를 적용하고 싶지 않아서 위와 같은 방법을 사용했지만, 만약 여러 페이지에서 다양한 레이아웃을 사용하고 싶다면, 각 페이지 파일에서 getLayout
함수를 정의하고 해당 함수를 통해 레이아웃을 반환할 수 있다고 한다.
// pages/_app.js
import Layout from '../components/Layout';
import { useRouter } from 'next/router';
function MyApp({ Component, pageProps }) {
const router = useRouter();
// getLayout 함수가 정의되어 있는 경우, 해당 함수를 사용하여 레이아웃을 가져옴
const getLayout = Component.getLayout || ((page) => <Layout>{page}</Layout>);
return getLayout(<Component {...pageProps} />);
}
export default MyApp;
// pages/login.js
import React from 'react';
const LoginPage = () => {
// 로그인 페이지에는 레이아웃을 적용하지 않음
return <div>Login Page Content</div>;
};
// getLayout 함수를 정의하지 않으면 자동으로 기본 레이아웃을 사용
LoginPage.getLayout = (page) => page;
export default LoginPage;
Seo 컴포넌트는 검색 엔진 최적화 (Search Engine Optimization)을 위한 목적으로 웹 페이지에 추가할 수 있는 React 컴포넌트 이다. 이 컴포넌트는 웹 페이지의 검색 엔진에서 인덱싱 및 랭킹에 영향을 미치도록 여러가지 정보를 제공한다고 한다. 주로 <head>
요소에 들어가는 메타 태그와 관련되 정보를 동적으로 설정하는 역할을 한다.
<Seo 컴포넌트의 역할>
react의 경우 이를 위해 react-helmet
과 같은 라이브러리를 사용해야 했지만, next에서는 Head
라는 컴포넌트로 추가적인 라이브러리 없이 이를 쉽게 구현할 수 있다.
// src/components/Seo.tsx
import Head from 'next/head';
import React from 'react';
type Props = {
title: string;
description: string;
keywords: string;
canonicalUrl: string;
};
const Seo = ({ title, description, keywords, canonicalUrl }: Props) => {
return (
<Head>
{/* 페이지 타이틀 */}
<title>{title} | BAPLE</title> // 우리 프로젝트 이름이 '베플' 이다.
{/* 페이지 설명 */}
<meta name="description" content={description} />
{/* 페이지 키워드 */}
<meta name="keywords" content={keywords} />
{/* 캐노니컬 URL */}
{canonicalUrl && <link rel="canonical" href={canonicalUrl} />}
</Head>
);
};
export default Seo;
Seo 컴포넌트는 다음과 같이 페이지에서 사용하면 된다.
// pages/index.js
import React from 'react';
import Seo from '../components/SEO';
const HomePage = () => {
return (
<div>
{/* Seo 컴포넌트 사용 */}
<Seo
title="홈 페이지"
description="이 페이지는 Next.js와 SEO 컴포넌트를 사용하는 예시입니다."
keywords="Next.js, SEO, React"
canonicalUrl="https://example.com/home"
/>
{/* 나머지 페이지 컨텐츠 */}
<h1>안녕하세요! 홈 페이지입니다.</h1>
</div>
);
};
export default HomePage;
이런 방식으로 Seo 컴포넌트를 사용하면 페이지마다 메타 태그를 동적으로 설정할 수 있다고 한다. 페이지의 title, description, keywords 등을 적절히 설정하여 검색엔진 최적화에 기여할 수 있다.
기획이 마무리 단계에 접어들고, 본격적인 개발에 착수하니까 점점 재미가 있어지는 것 같다. (기획이 제일 힘들어....)
물론 개발 하면서 무수히 많은 에러들과 버그들을 마주하겠지만... 😂
하니씩.. 뿌셔보자....!!