// next.config.js
// .env에서 API_KEY 가져오기
const API_KEY = process.env.API_KEY;
/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
swcMinify: true,
}
module.exports = {
nextConfig,
async redirects() {
return [
{
source: '/contact',
destination: '/form',
permanent: false,
},
{
source: '/old-blog/:path*',
destination: '/new-blog/:path*',
permanent: false,
}
]
},
async rewrites() {
return [
{
source: '/api/movies',
destination: `https://api.themoviedb.org/3/movie/popular?api_key=${API_KEY}`
},
// id 가져오는 rewrite
{
// :id로 변수 설정
source: '/api/movies/:id',
// 위 destination 링크에서 popular만 :id로 변경
destination: `https://api.themoviedb.org/3/movie/:id?api_key=${API_KEY}`
}
]
}
}
// index.js
import Link from "next/link";
import { useRouter } from "next/router";
import Seo from "./Seo"
export default function Home({results}) {
// router를 이용하여 페이지 이동 함수 만들기
const router = useRouter();
// 매개변수에 title 추가
function onClick(id, title) {
// push의 첫 매개변수: 이동할 url
router.push({
// pathname: 이동할 url
pathname: `/movies/${id}`,
// query: url에 쿼리로 나타낼 내용(? 뒷부분에 &로 구분하여 나타냄)
// 숨겨지더라도 개발자도구 query에 나타남. 이를 이용해 제목도 전달 받을 수 있음
query: {
title,
}
// push의 두 번째 매개변수: as(겉으로 보여질 url)
}, `/movies/${id}`);
}
return (
<div className="container">
<Seo title='Home' />
{results?.map(movie => (
// onClick에 매개변수를 넣어줘야하므로 콜백 함수 형태로 만듬
<div onClick={() => onClick(movie.id, movie.original_title)} className="movie" key={movie.id}>
<img src={`https://image.tmdb.org/t/p/w500${movie.poster_path}`} />
<h4>
{/* Link에 href 설정 후 a태그로 제목 감싸기 */}
{/* Link로 링크 이동을 원한다면 router.push와 같은 형태로 만들어줘야 함(href와 as 프로퍼티 이용) */}
<Link href={{
pathname: `/movies/${movie.id}`,
query: {
title: movie.original_title,
}
}} as={`/movies/${movie.id}`}>
<a>
{movie.original_title}
</a>
</Link>
</h4>
</div>
))}
<style jsx> {`
.container {
display: grid;
grid-template-columns: 1fr 1fr;
padding: 20px;
gap: 20px;
}
.movie {
cursor: pointer;
}
.movie img {
max-width: 100%;
border-radius: 12px;
transition: transform 0.2s ease-in-out;
box-shadow: rgba(0, 0, 0, 0.1) 0px 4px 12px;
}
.movie:hover img {
transform: scale(1.05) translateY(-10px);
}
.movie h4 {
font-size: 18px;
text-align: center;
}
`}
</style>
</div>
)
}
export async function getServerSideProps() {
const {results} = await (await fetch('http://localhost:3000/api/movies')).json();
return {
props: {
results,
}
}
}
// [id].js
import { useRouter } from "next/router";
export default function Detail() {
const router = useRouter();
console.log(router);
return (
<div>
{/* router.query.title은 Home에서 클릭으로 넘어왔을 때만 존재 */}
{/* 링크로 직접 들어오면 Loading만 뜸 */}
<h4>{router.query.title || "Loading..."}</h4>
</div>
);
}
router 변수에 useRouter 할당
router.push는 navigate해주는 함수
/movies/${id}
처럼 그냥 주소만 적어줘도 됨/movies/${id}
처럼 생으로 적어줌as가 없을 때(원래 query에 id, title이 있었음)
as가 있을 때
url에는 안 보이지만 [id].js에서 router를 console에 찍어보면 쿼리들이 잘 있음
즉!!! 쿼리를 통해 정보를 받을 수 있다는 말씀!!
그래서 title까지 onClick으로 받아 [id].js에 띄워준다~~
하지만 onClick으로 만든 만큼 클릭을 통해 들어갈 때만 router.push가 작동하고, 직접 url을 쳐서 들어가면 [id].js에 써있는 것처럼 'Loading...'이 뜬다.
<Link key={movie.id}>
와 <a>
로 묶어주기(key 옮기는 거 안 하면 에러)