티스토리 뷰

사이드 프로젝트/🩺 바디토리 : 건강기록 및 병원추천 웹서비스

next.js에서 _next/static과 public/static

2022. 11. 27. 10:26

👿 이슈상황

 

랜딩페이지(토리가 등장해서 인사하는 페이지)를 구현한 후 원래 로그인 페이지로 연결되어있던 기본 URL을

랜딩페이지로 연결되도록 설정하고 접속하니 아래와 같은 에러가 발생했다.

 

 

 

 

 

 

💡 해결과정

 

에러 메세지를 검색해보니 json경로가 잘못되어 발생하는 에러라고 한다.

 

Failed to read the responseText error. · Issue #1925 · airbnb/lottie-web

I am exported an animation using latest version of bodymovin plugin but unable to get it work. works fine on demo file but not on the live page. data.zip Also, does it matter if i rename the data.j...

github.com

 

 

랜딩페이지에 들어가있는 lottie에 해당하는 json파일 경로(localhost:3000/static/lottie/tory_white.json)를

주소창에 직접 입력해보니 로그인이 되어있는 상태에서 위 경로를 입력하면 json파일이 정상적으로 보여지는데

로그인을 하지 않은 상태에서 위 경로를 입력하면 루트 경로(현재의 경우 랜딩페이지)로 리다이렉트 되었다.

 

리다이렉트 되는 코드는 middleware.ts에 작성되어있었는데 이 middleware.ts는 서버 환경에서 페이지 깜빡임 없이

리다이렉트를 시키기 위해 백엔드 담당 팀원이 작성하였다.

import { getIronSession } from "iron-session/edge";
import { NextRequest, NextResponse, userAgent } from "next/server";

export async function middleware(req: NextRequest) {
  const res = NextResponse.next();
  const session = await getIronSession(req, res, {
    cookieName: "userSession",
    password: process.env.COOKIE_PASSWORD!,
  });
  if (req.url.includes("/users/records/write/add") || req.url.includes("/users/records/write/analysis")) {
    if (!req.nextUrl.search.includes("position")) return NextResponse.redirect(new URL("/", req.url));
  }

  if (
    !session.user &&
    !req.url.includes("/auth/login") &&
    !req.url.includes("/auth/help") &&
    !req.url.includes("/auth/register") &&
    !req.url.includes("/auth/choice") &&
    !req.url.includes("/landing") &&
    !req.url.includes("/hospital/login") &&
    !req.url.includes("/about/team") &&
    !req.url.includes("/about/bodytory")
  ) {
    if (req.url.includes("/hospital/chart" && "/hospital/chart" && "/hospital"))
      return NextResponse.redirect(new URL("/hospital/login", req.url));
    return NextResponse.redirect(new URL("/landing", req.url));
  } else if (
    session.user &&
    (req.url.includes("auth/login") ||
      req.url.includes("/auth/help") ||
      req.url.includes("/landing") ||
      (req.url.includes("/auth/register") && !req.url.includes("/success")))
  ) {
    return NextResponse.redirect(new URL("/", req.url));
  }
}

export const config = {
  matcher: ["/((?!api|_next/static|favicon.ico).*)"],
};

 

위 코드에서 이 이슈에 필요한 부분만 간단히 요약하자면 matcher에 해당하는 경로에 접근할 때마다 

middleware가 동작하는데 현재 matcher에 작성되어있는 

["/((?!api|_next/static|favicon.ico).*)"] 는 api , _next/static , favicon.ico 를 제외한 모든 페이지를 의미한다.

 

 

 

현재 lottie json파일들은 public/static/lottie 경로에 존재한다.

 

나는 여기서 matcher에 _next/static 경로가 추가되어있으니 로그인이 되어있지 않을 때 

static 경로에 접근하면 middleware에 걸리지 않을 줄 알았는데 현재 상황으로는 middleware에 걸리고 있었다. 

 

middleware에 걸린다는 건 matcher에서 제외시키는 로직에 포함되지 않았다는 것인데 

lottie json파일과 같은 경로에 있는 favicon의 경로를 주소창에 직접 입력해보니 잘 제외되고 있었다.

 

그래서 _next/static에 대해 찾아보니 _next/static은 이미지처럼 next에서 최적화한 다음에 넣는 static경로 같은거라

pubilc에 만든 static 폴더와는 다른 것이라고 한다.

 

서비스 소개 페이지에 있는 image의 경로를 브라우저 콘솔에서 확인해보니 _next/static 경로에 있는 것을 확인할 수 있었다.

 

 

 

따라서 현재 matcher에 public/static은 포함이 되지 않고 있던 것이고 그래서 json경로들이 미들웨어에 걸려서 루트경로로 리다이렉트 되고 있었던 것이다.

 

matcher에 | static 을 추가하니 에러가 해결되었다.

export const config = {
  matcher: ["/((?!api|_next/static|favicon.ico|static).*)"],
};

 

 

 

next.js 공식문서에서 참고 자료를 볼 수 있다.

 

Routing: Middleware | Next.js

Learn how to use Middleware to run code before a request is completed.

nextjs.org

 

반응형
프로필사진
개발자 삐롱히

프론트엔드 개발자 삐롱히의 개발 & 공부 기록 블로그