TIL. Next.js

Yang⭐·2023년 2월 15일
0
post-thumbnail

Nextjs는 왜 쓰는가

외부 노출을 통해 마케팅이 필요한 웹사이트 제작 시 SEO 및 시멘틱 태그를 사용하는게 큰 영향을 끼치는 것을 알게되었다.

그러면서 기존 Vite + React + tysctipt 템플릿을 사용해 제작된 사이트의 SEO작업을 진행했는데 Vite 공식사이트 내의 SSR관련 문서는 아직 시범단계인지라 매우매우매우 부족했다.

그러다 결국 최후의 방법으로 Next.js로 마이그레이션 하는 방법을 택했다.

여기서 Gatsby를 사용할 것인가, Next.js를 사용할 것인가 고민이 있었다.
결론은 Gatsby는 graphQL을 사용해야 한다는 부분에서 Next로 결정되었다.

Next.js 는 React를 서버사이드 렌더링 시켜줄 수 있는 프레임워크이다.
프레임워크인 만큼 사용법이 있고 이에 맞춰서 사용해야 하는 점이 있다.

서버사이드 렌더링을 통해 텅 빈 html이 아닌 시멘틱 태그들과 SEO가 잘 적용된 static html을 얻는 것이 목표였따.

Routing

React와 가장 큰 차이점이 라우팅이었다.
react-router-dom을 사용했던 기존방식에서 ONLY 디렉토리 구조만으로 라우팅한다.
router 파일들을 관리 안해도 된다는 점에서 편리했지만 path parameter가 여러개 붙는 페이지는 구조가 복잡해진다.

// ex) http://localhost:3000/:receipt/:mid/:tid/:id

├─receipt
│  └─[mid]
│      └─[tid][id].tsx
│...

Next로 배포 시에만 특정 페이지가 404가 뜨는 적이 있었다.
pages폴더 내에 생성했던 pahhname.tsx파일을 pathname폴더 생성 후 index파일로 구조를 변경하니 해결되었따.

// 404
├─pages
│  └─mood.tsx
// 해결
├─pages
│  └─mood
│      └─index.tsx

redirect & rewrite

// next.config.js
async redirects() {
    return [
      {
        source: "/login",
        destination: "/join",
        permanent: false,
      },
    ];
  },
  async rewrites() {
    return [
      {
        source: "/api/movies",
        destination: `https://api.themoviedb.org/3/movie/popular?api_key=${API_KEY}`,
      },
    ];
  },
};

// api.ts
const res = await fetch('/api/movies')
  • redirects = source url → destination url 로 return 시켜줌
  • rewrites = source url을 새로고침 없이 destination으로 redirect
    api 를 source 주소로 destination의 주소로 보내기에 민감한 값을 마스킹 할 수 있음 ( = params에 중요정보 숨기기 가능)
    pre-renderer방법x (클라이언트에서 api사용)

getServerSideProps

export async function getServerSideProps() {
  const { results } = await (
    await fetch(`http://localhost:3000/api/movies`)
  ).json();
  return {
    props: {
      results,
    },
  };
}

// home 컴포넌트 내 props로 전달

Dynamic Route를 사용할 경우 미리 pre-renderer

export default function Detail({ params }) {
  const router = useRouter();
  const [title, id] = params || [];
  return (
    <div>
      <h4>{title}</h4>
    </div>
  );
}

export function getServerSideProps({ params: { params } }) {
  return {
    props: {
      params,
    },
  };
}

위와 같이 동적 경로를 사용할 경우 미리 title을 pre-renderer를 하기에 html파일 내 title이 포함된 파일을 받을 수 있음

💡 언제 getServerSideProps를 사용해야 하나요?

request time에 반드시 데이터를 fetch해와야 하는 페이지를 pre-render해야 하는 경우.

데이터를 pre-render할 필요가 없다면 client side에서 데이터를 가져오는 것을 고려해야한다.

예를들어 대쉬보드같은 사용자별 비공개 페이지는 SEO와 관련이 없으며 페이지를 미리 렌더링 할 필요가 없으니 클라이언트 측에서 데이터를 가져올 수 있음

Dynamic Route

// pages/movies/index.ts -> /movies
// pages/movies/[id].ts -> /movies/123

const {asPath} = useRouter()

// '/movies/123'
const router = useRouter();

//
const onClick = (path:string) => {
	router.push(
      {
        pathname: `/movies/${id}`,
        query: {
          title,
        },
      },
      `/movies/${id}` // as?: url을 해당 url로 마스킹
    );
}

// === same

<Link
		href={{
			pathname: `/movies/${movie.id}`,
			query: {
				title: movie.original_title,
			},
		}}
		as={`/movies/${movie.id}`}
>
	<a>{...}</a>
</Link>

클라이언트 측 전환을 처리합니다. 이 방법은 next/link가 충분하지 않은 경우에 유용.

url: UrlObject | String: 탐색할 URL

as: UrlObject | String: 브라우저 URL 표시줄에 표시될 경로에 대한 선택적 데코레이터.

외부 URL에 대해서는 router.push()를 사용할 필요가 없음
window.location을 사용하는 것이 더 적합.

Next.js 13버전에 추가된 부분

app/ Directory (beta)

  • page 디렉토리 / index.ts → app 디렉토리 / page.ts 기본 라우터

Layout

layout.ts → 모든페이지 해당 레이아웃 적용가능

스트리밍

app 디렉토리에서 loading.js라는 예약 파일을 생성하여 사용자가 렌더링이 되기 이전에 로딩 중인 화면을 표시할 수 있는 기능이다.

Data Fetching

함수를 선언한 뒤에, use() 안에 넣어주기만 하면 된다. 추가적으로, fetch 구문의 URL 뒤에 { cache: '' }
를 넣어줄 수 있는데, 안에 무엇이 들어가냐에 따라 기존의 getServerSideProps, getStaticProps와 유사한 기능을 할 수 있다.

next/Image

Image 컴포넌트를 통해서 이미지가 자동으로 최적화 가능.

이미지 로드가 느릴 경우에 기존의 레이아웃이 밀려나는 현상인 Layout Shift가 발생하는데, 이를 방지하기 위해 이미지의 width와 height를 설정해야만 한다.
Next.js 13 버전에서는 이를 자동으로 처리해주기 때문에, 최적화에 유용하다.

또한, 이제 alt 속성을 필요로 하기 때문에 웹 접근성 향상이 되었다.

<Link> 태그 내에  <a> 태그를 더이상 자식 요소로 필요하지 않음 → 기본 태그에도 props를 전달할 수 있다.

reference

nextjs 13버전

0개의 댓글