Posts

[Next] Catch All URL

목차2

Catch ALL URL

pages 하위에 파일명을 [...params].js(원하는 이름 사용) 와 같이 설정하면 어떤 URL이라도 잡을 수 있다.

[...] 를 통해서 movies라는 폴더 아래 모든 Endpoint를 라우팅 할 수 있다.

Link 태그의 href 속성을 수정할 수 있다.

코드
<Link href={`/movie/${movie.original_title}/${movie.id}`}>{movie.original_title}</Link>;

useRouter 를 사용해 params 배열을 구조분해할당해서 사용할 수 있다.

코드
import { useRouter } from 'next/router';
export default function Detail() {
  const router = useRouter();
  const [title, id] = router.query.params;
  return (
    <div>
      <h2>{title || 'Loading...'}</h2>
    </div>
  );
}
// url s== "/movies/title/id"

콘솔로 찍은 router의 query안에 있는 params는 배열이다.

하지만 서버에서는 아직 params가 배열이 아니므로, 시크릿 모드로 캐시가 모두 사라진 경우에 query가 담긴 url로 접근하려고 하면 오류가 발생한다.

따라서 빈배열 [] 를 아래처럼 추가해주어야 오류가 발생하지 않는다.

코드
const router = useRouter();
const [title, id] = router.query.params || [];

하지만 여기까지는 CSR과정만 진행한 것이다.


getServerSideProps 사용

첫번째 인수 ctx 에는 query 와 params 정보들이 담겨져 있다.

이를 사용해서 pre-rendering 해주면 된다.

코드
import { useRouter } from 'next/router';

export default function Detail() {
  const router = useRouter();
  const [title, id] = router.query - params || [];
  return (
    <div>
      <h2>{title || 'loading... '}</h2>{' '}
    </div>
  );
}
// url == "/movies/title/id"

export async function getServerSideProps(ctx) {
  console.log(ct); // query, params 정보들
  return {
    props: {},
  };
}

getServerSideProps를 사용해 ctx를 콘솔에 찍어보면 브라우저가 아닌 서버에 나타나는 것을 볼 수 있다.

이를 사용해 pre-rendering을 해준다.

코드
import { useRouter } from 'next/router';

export default function Detail() {
  const router = useRouter();
  const [title, id] = router.query - params || [];
  return (
    <div>
      <h2>{title || 'loading... '}</h2>{' '}
    </div>
  );
}
// url == "/movies/title/id"

export async function getServerSideProps({ params: { params } }) {
  console.log(ct); // query, params 정보들
  return {
    props: { params },
  };
}

라우터의 객체를 구조분해할당하여 Seo컴포넌트에 title이라는 prop을 전달하여 해당 컴포넌트에서 Head태그를 통해 title을 수정 할 수 있다.

코드
import Seo from './../components/Seo';
import { useRouter } from 'next/router';

export default function Detail({ params }) {
  const router = useRouter();
  const [title, id] = params || [];
  return (
    <div>
      <Seo title={title} /> <h4>{title}</h4>
    </div>
  );
}
코드
import Head from 'next/head';
export default function Seo({ title }) {
  return (
    <Head>
      <title>{title} | Next Movies</title>
    </Head>
  );
}

반응형