티스토리 뷰
Catch-all URL 이란
아래 사진과 같이 url 뒤에 붙여진 parameter 값을 다 받아오는것을 말합니다.
위 URL 에 영화 제목을 넣어 SEO 최적화를 시켜줄겁니다.
이 방법을 사용하게 되면 영화의 제목을 바로 받아올 수 있을 뿐더러 홈페이지에서
클릭 후 상세페이지를 들어오지 않더라도 영화의 제목을 확인할 수 있게됩니다.
우선 index.js URL 라우팅을 다음과 같이 영화제목도 url에 들어갈 수 있도록 바꿔줍니다.
[...] 으로 Catch-All
그리고 이전에 만들었던 pages > movies > [id].js의 파일명을 [...params].js 로 바꿔줍니다.
여기서 id > params 로 바꾼 이유는 더이상 id의 파일명 보다는 catch all 할 url이 하나의 parameter query를 받아올것이 아니기때문에 더 적절한 params 로 바꾸어주었고 앞에 ...을 추가하게 되면 url 을 catch-all 하게 되어 router에서 query로 받아올 수 있습니다.
그리고 해당 파일에서 router을 console log를 찍어보면
다음과 같이 query의 값이 더이상 object형식의 string으로 반환을 시키지 않고 배열 형식의 값을 반환합니다.
배열 재 분할
배열 재 분할을 통해서 router query의 미리 이름을 정해두었던 params의 값을 받아오도록 하겠습니다.
다음과 같이 router.query.params의 Array의 길이가 2개라는것을 미리 알고 있기에
0번째 영화의 제목, 1번째 영화의 id 값을 다음과 같이 받아올 수 있습니다.
아래와 같이 params 안에 들어가있는것을 확실히 알고 있을때만 말이죠.
router.query.params : ["영화제목", "영화 id"]
// [...params].js
import { useRouter } from "next/router";
export default function Detail() {
const router = useRouter();
const [movieTitle, movieId] = router.query.params;
return (
<div>
<h4>{movieTitle || "Loading..."}</h4>
</div>
);
}
home에서 영화를 클릭하고 들어오면 발생하지않지만 이것은 에러를 발생시킵니다.
왜냐면 서버에는 아직 router.query.params가 없고 아직 배열이 아니기 때문이죠.
재분할 에러 핸들링
재 분할과정에서 해당 값이 없을때 에러가 나지 않으려면 다음과 같은 문법을 사용하면 됩니다.
const [movieTitle, movieId] = router.query.params || [];
그러면 해당 페이지에서 새로고침을 하여도 에러가 나지 않게됩니다.
getServerSideProps Context
하지만 위의 방법보다 더 나은 SEO 경험을 만들수 있습니다.
그 이전에 브라우저에서 받아온 Source 파일을 살펴봅니다.
아래와 같이 영화의 제목이 포함되지 않은채로 html 파일을 받아옵니다.
html 파일에 영화 제목을 포함시킨 채로 받아오는 방법은 없을까요?
getServerSideProps Context라는것을 사용하면됩니다!
[...parmas].js 파일에 getServerSideProps() 함수를 추가해주고 인자값으로 ctx를 넣고 console을 찍어봅니다.
// [...params].js
import { useRouter } from "next/router";
export default function Detail() {
const router = useRouter();
const [movieTitle, movieId] = router.query.params || [];
return (
<div>
<h4>{movieTitle || "Loading..."}</h4>
</div>
);
}
export async function getServerSideProps(ctx) {
console.log(ctx);
return {
props: {},
};
}
getServerSideProps함수에서 찍은 console.log는 실행시킨 cmd 창에서 확인할 수 있습니다.
다음 cmd 창의 사진과 같이 params.params 값으로 영화 제목과 id 를 볼 수 있습니다.
자 그럼 서버에서는 params 의 params값을 props로 넘겨주고,
export async function getServerSideProps({ params: { params } }) {
return {
props: {
params,
},
};
}
클라이언트에서는 그 값을 받아서 처리해줍니다.
export default function Detail({ params }) {
const router = useRouter();
const [movieTitle, movieId] = params;
return (
<div>
<h4>{movieTitle}</h4>
</div>
);
}
최종적인 [...params].js 코드입니다.
import { useRouter } from "next/router";
export default function Detail({ params }) {
const router = useRouter();
const [movieTitle, movieId] = params;
return (
<div>
<h4>{movieTitle}</h4>
</div>
);
}
export async function getServerSideProps({ params: { params } }) {
return {
props: {
params,
},
};
}
이전과 같이 영화 제목을 잘 보여줍니다.
또한 Source 파일을 보게되면 html 파일에도 영화 제목이 포함되어 파일을 받게됩니다.
위의 방식과 같이 하게되면 불 필요한 API 호출을 최소화 할 뿐더러 로딩속도,
SEO 최적화까지 노릴수 있는 장점들을 가져갈 수 있습니다.
'Next.js > 기초 공부 시작( 겉핥기 )' 카테고리의 다른 글
Next js 404Page / 수박 겉핥기 공부 끝 (2) | 2022.04.12 |
---|---|
Next js Dynamic Routes / 중첩 라우팅 / URL 변수 / router state 전달 및 마스킹 (0) | 2022.04.11 |
Next js SSR : get server side props (0) | 2022.04.10 |
Next js ( Redirect / Rewrite ) , Rewrite 로 API key를 숨기자 (0) | 2022.04.10 |
Next js Fetching Data / public 경로 (1) | 2022.04.10 |