next.js file Based Routing

정영찬·2023년 5월 21일
0

Next.js

목록 보기
4/10
post-thumbnail

next.js 13 버전에서는 app 폴더 내부의 page.tsx가 메인 페이지로 접속했을때 보여주게 되는 화면이다.

물론 메인 페이지 내부에서 /search 경로 페이지로 이동한다면 이런 식으로 파일을 만들면된다.

같은 방법으로 /restaurant 경로를 만들고 싶다면 restaurant 폴더를 생성해주고 page.tsx파일을 만들면 된다!

각각의 경로 폴더 내부에 page.tsx를 작성해서 파일의 이름으로 라우팅 해주는 기능을 바로 file Based Routing 이라고 한다.

그렇다면 이제 해당 page.tsx에 우리가 원하는 html 코드만 작성해주면, 원하는 페이지에 원하는 화면이 나올 것이다.

메인페이지를 한번 적용시켜보자. 각각의 page.tsx 내부에 html 코드를 작성해주면 된다.

메인 페이지

<main className="bg-gray-100 min-h-screen w-screen">
  <main className="max-w-screen-2xl m-auto bg-white">
    {/* NAVBAR */}
    <nav className="bg-white p-2 flex justify-between">
      <a href="" className="font-bold text-gray-700 text-2xl"> OpenTable </a>
      <div>
        <div className="flex">
          <button
            className="bg-blue-400 text-white border p-1 px-4 rounded mr-3"
          >
            Sign in
          </button>
          <button className="border p-1 px-4 rounded">Sign up</button>
        </div>
      </div>
    </nav>
    {/* NAVBAR */}
    <main>
      {/* HEADER */}
      <div className="h-64 bg-gradient-to-r from-[#0f1f47] to-[#5f6984] p-2">
        <div className="text-center mt-10">
          <h1 className="text-white text-5xl font-bold mb-2">
            Find your table for any occasion
          </h1>
          {/* SEARCH BAR */}
          <div className="text-left text-lg py-3 m-auto flex justify-center">
            <input
              className="rounded  mr-3 p-2 w-[450px]"
              type="text"
              placeholder="State, city or town"
            />
            <button className="rounded bg-red-600 px-9 py-2 text-white">
              Let's go
            </button>
          </div>
          {/* SEARCH BAR */}
        </div>
      </div>
      {/* HEADER */} {/* CARDS */}
      <div className="py-3 px-36 mt-10 flex flex-wrap justify-center">
        {/* CARD */}
        <div
          className="w-64 h-72 m-3 rounded overflow-hidden border cursor-pointer"
        >
          <img
            src="https://resizer.otstatic.com/v2/photos/wide-huge/2/31852905.jpg"
            alt=""
            className="w-full h-36"
          />
          <div className="p-1">
            <h3 className="font-bold text-2xl mb-2">Milestones Grill</h3>
            <div className="flex items-start">
              <div className="flex mb-2">*****</div>
              <p className="ml-2">77 reviews</p>
            </div>
            <div className="flex text-reg font-light capitalize">
              <p className=" mr-3">Mexican</p>
              <p className="mr-3">$$$$</p>
              <p>Toronto</p>
            </div>
            <p className="text-sm mt-1 font-bold">Booked 3 times today</p>
          </div>
        </div>
        {/* CARD */}
      </div>
      {/* CARDS */}
    </main>
  </main>
</main>

검색 페이지 (/search)

import Image from 'next/image'
export default function Search() {
  return (
    <main className="w-screen min-h-screen bg-gray-100">
      <main className="m-auto bg-white max-w-screen-2xl">
        {/* NAVBAR */}
        <nav className="flex justify-between p-2 bg-white">
          <a href="" className="text-2xl font-bold text-gray-700">
            {' '}
            OpenTable{' '}
          </a>
          <div>
            <div className="flex">
              <button className="p-1 px-4 mr-3 text-white bg-blue-400 border rounded">
                Sign in
              </button>
              <button className="p-1 px-4 border rounded">Sign up</button>
            </div>
          </div>
        </nav>
        {/* HEADER */}
        <div className="bg-gradient-to-r to-[#5f6984] from-[#0f1f47] p-2">
          <div className="flex justify-center py-3 m-auto text-lg text-left">
            <input
              className="rounded  mr-3 p-2 w-[450px]"
              type="text"
              placeholder="State, city or town"
            />
            <button className="py-2 text-white bg-red-600 rounded px-9">Let's go</button>
          </div>
        </div>
        <div className="flex items-start justify-between w-2/3 py-4 m-auto">
          {/* SEARCH SIDE BAR */}
          <div className="w-1/5">
            <div className="pb-4 border-b">
              <h1 className="mb-2">Region</h1>
              <p className="font-light text-reg">Toronto</p>
              <p className="font-light text-reg">Ottawa</p>
              <p className="font-light text-reg">Montreal</p>
              <p className="font-light text-reg">Hamilton</p>
              <p className="font-light text-reg">Kingston</p>
              <p className="font-light text-reg">Niagara</p>
            </div>
            <div className="pb-4 mt-3 border-b">
              <h1 className="mb-2">Cuisine</h1>
              <p className="font-light text-reg">Mexican</p>
              <p className="font-light text-reg">Italian</p>
              <p className="font-light text-reg">Chinese</p>
            </div>
            <div className="pb-4 mt-3">
              <h1 className="mb-2">Price</h1>
              <div className="flex">
                <button className="w-full p-2 font-light border rounded-l text-reg">$</button>
                <button className="w-full p-2 font-light border-t border-b border-r text-reg">
                  $$
                </button>
                <button className="w-full p-2 font-light border-t border-b border-r rounded-r text-reg">
                  $$$
                </button>
              </div>
            </div>
          </div>
          {/* SEARCH SIDE BAR */}
          <div className="w-5/6">
            {/* RESAURANT CAR */}
            <div className="flex pb-5 border-b">
              <img
                src="https://images.otstatic.com/prod1/49153814/2/medium.jpg"
                alt=""
                className="rounded w-44"
              />
              <div className="pl-5">
                <h2 className="text-3xl">Aiāna Restaurant Collective</h2>
                <div className="flex items-start">
                  <div className="flex mb-2">*****</div>
                  <p className="ml-2 text-sm">Awesome</p>
                </div>
                <div className="mb-9">
                  <div className="flex font-light text-reg">
                    <p className="mr-4">$$$</p>
                    <p className="mr-4">Mexican</p>
                    <p className="mr-4">Ottawa</p>
                  </div>
                </div>
                <div className="text-red-600">
                  <a href="">View more information</a>
                </div>
              </div>
            </div>
            {/* RESAURANT CAR */}
          </div>
        </div>
      </main>
    </main>
  )
}

식당 상세 페이지(/restaurant/[slug]/)
[slug] 은 어떤 값이던 들어갈수 있다. 따라서 어떤 식당이던 선택했을때 상세페이지를 보여주는 경로 설정을 하고 싶다면 이렇게 [slug]를 하위 경로에 추가하고 그 안에 page.tsx를 작성해주면 된다.

<main className="bg-gray-100 min-h-screen w-screen">
  <main className="max-w-screen-2xl m-auto bg-white">
    {/* NAVBAR */}
    <nav className="bg-white p-2 flex justify-between">
      <a href="" className="font-bold text-gray-700 text-2xl">
        {" "} OpenTable{" "}
      </a>
      <div>
        <div className="flex">
          <button
            className="bg-blue-400 text-white border p-1 px-4 rounded mr-3"
          >
            Sign in
          </button>
          <button className="border p-1 px-4 rounded">Sign up</button>
        </div>
      </div>
    </nav>
    {/* NAVBAR */} {/* HEADER */}
    <div className="h-96 overflow-hidden">
      <div
        className="bg-center bg-gradient-to-r from-[#0f1f47] to-[#5f6984] h-full flex justify-center items-center"
      >
        <h1 className="text-7xl text-white captitalize text-shadow text-center">
          Milestones Grill (Toronto)
        </h1>
      </div>
    </div>
    {/* HEADER */} {/* DESCRIPTION PORTION */}
    <div className="flex m-auto w-2/3 justify-between items-start 0 -mt-11">
      <div className="bg-white w-[100%] rounded p-3 shadow">
        {/* RESAURANT NAVBAR */}
        <nav className="flex text-reg border-b pb-2">
          <a href="" className="mr-7"> Overview </a>
          <a href="" className="mr-7"> Menu </a>
        </nav>
        {/* RESAURANT NAVBAR */} {/* MENU */}
        <main className="bg-white mt-5">
          <div>
            <div className="mt-4 pb-1 mb-1">
              <h1 className="font-bold text-4xl">Menu</h1>
            </div>
            <div className="flex flex-wrap justify-between">
              {/* MENU CARD */}
              <div className=" border rounded p-3 w-[49%] mb-3">
                <h3 className="font-bold text-lg">Surf and Turf</h3>
                <p className="font-light mt-1 text-sm">
                  A well done steak with lobster and rice
                </p>
                <p className="mt-7">$80.00</p>
              </div>
              {/* MENU CARD */}
            </div>
          </div>
        </main>
        {/* MENU */}
      </div>
    </div>
    {/* DESCRIPTION PORTION */}
  </main>
</main>

식당 메뉴 페이지
(/restaurant/[slug]/menu)

이런 경로로 구현하려면 [slug] 경로 안에 menu폴더를 만들어서 거기에 page.tsx를 만들어주면 된다.

import Image from 'next/image'
export default function RestaurantMenu() {
  return (
    <main className="w-screen min-h-screen bg-gray-100">
      <main className="m-auto bg-white max-w-screen-2xl">
        {/* NAVBAR */}
        <nav className="flex justify-between p-2 bg-white">
          <a href="" className="text-2xl font-bold text-gray-700">
            {' '}
            OpenTable{' '}
          </a>
          <div>
            <div className="flex">
              <button className="p-1 px-4 mr-3 text-white bg-blue-400 border rounded">
                Sign in
              </button>
              <button className="p-1 px-4 border rounded">Sign up</button>
            </div>
          </div>
        </nav>
        {/* NAVBAR */} {/* HEADER */}
        <div className="overflow-hidden h-96">
          <div className="bg-center bg-gradient-to-r from-[#0f1f47] to-[#5f6984] h-full flex justify-center items-center">
            <h1 className="text-center text-white text-7xl captitalize text-shadow">
              Milestones Grill (Toronto)
            </h1>
          </div>
        </div>
        {/* HEADER */} {/* DESCRIPTION PORTION */}
        <div className="flex items-start justify-between w-2/3 m-auto 0 -mt-11">
          <div className="bg-white w-[100%] rounded p-3 shadow">
            {/* RESAURANT NAVBAR */}
            <nav className="flex pb-2 border-b text-reg">
              <a href="" className="mr-7">
                {' '}
                Overview{' '}
              </a>
              <a href="" className="mr-7">
                {' '}
                Menu{' '}
              </a>
            </nav>
            {/* RESAURANT NAVBAR */} {/* MENU */}
            <main className="mt-5 bg-white">
              <div>
                <div className="pb-1 mt-4 mb-1">
                  <h1 className="text-4xl font-bold">Menu</h1>
                </div>
                <div className="flex flex-wrap justify-between">
                  {/* MENU CARD */}
                  <div className=" border rounded p-3 w-[49%] mb-3">
                    <h3 className="text-lg font-bold">Surf and Turf</h3>
                    <p className="mt-1 text-sm font-light">
                      A well done steak with lobster and rice
                    </p>
                    <p className="mt-7">$80.00</p>
                  </div>
                  {/* MENU CARD */}
                </div>
              </div>
            </main>
            {/* MENU */}
          </div>
        </div>
        {/* DESCRIPTION PORTION */}
      </main>
    </main>
  )
}

식당 예약 페이지 (/restaurant/reserve/[slug])

<main className="bg-gray-100 min-h-screen w-screen">
  <main className="max-w-screen-2xl m-auto bg-white">
    {/* NAVBAR */}
    <nav className="bg-white p-2 flex justify-between">
      <a href="" className="font-bold text-gray-700 text-2xl">
        {" "} OpenTable{" "}
      </a>
      <div>
        <div className="flex">
          <button
            className="bg-blue-400 text-white border p-1 px-4 rounded mr-3"
          >
            Sign in
          </button>
          <button className="border p-1 px-4 rounded">Sign up</button>
        </div>
      </div>
    </nav>
    {/* NAVBAR END */}
    <div className="border-t h-screen">
      <div className="py-9 w-3/5 m-auto">
        {/* HEADER */}
        <div>
          <h3 className="font-bold">You're almost done!</h3>
          <div className="mt-5 flex">
            <img
              src="https://images.otstatic.com/prod1/49153814/2/medium.jpg"
              alt=""
              className="w-32 h-18 rounded"
            />
            <div className="ml-4">
              <h1 className="text-3xl font-bold">
                Aiāna Restaurant Collective
              </h1>
              <div className="flex mt-3">
                <p className="mr-6">Tues, 22, 2023</p>
                <p className="mr-6">7:30 PM</p>
                <p className="mr-6">3 people</p>
              </div>
            </div>
          </div>
        </div>
        {/* HEADER */} {/* FORM */}
        <div className="mt-10 flex flex-wrap justify-between w-[660px]">
          <input
            type="text"
            className="border rounded p-3 w-80 mb-4"
            placeholder="First name"
          />
          <input
            type="text"
            className="border rounded p-3 w-80 mb-4"
            placeholder="Last name"
          />
          <input
            type="text"
            className="border rounded p-3 w-80 mb-4"
            placeholder="Phone number"
          />
          <input
            type="text"
            className="border rounded p-3 w-80 mb-4"
            placeholder="Email"
          />
          <input
            type="text"
            className="border rounded p-3 w-80 mb-4"
            placeholder="Occasion (optional)"
          />
          <input
            type="text"
            className="border rounded p-3 w-80 mb-4"
            placeholder="Requests (optional)"
          />
          <button
            className="bg-red-600 w-full p-3 text-white font-bold rounded disabled:bg-gray-300"
          >
            Complete reservation
          </button>
          <p className="mt-4 text-sm">
            By clicking “Complete reservation” you agree to the OpenTable Terms
            of Use and Privacy Policy. Standard text message rates may apply.
            You may opt out of receiving text messages at any time.
          </p>
        </div>
      </div>
    </div>
  </main>
</main>

  • app 바로 하위의 page.tsx -> 메인 페이지
  • app 하위 폴더 내부의 page.tsx -> 하위 경로 페이지 ex) app/restaurant/page.tsx -> /restaurant
  • 경로의 이름을 동적으로 부여하고 싶다면 [slug]를 사용하자 ex) restaurant/[slug]/page.tsx -> /restaurant/shakeshake
profile
개발자 꿈나무

0개의 댓글