본문 바로가기

개발/Front-end

[이슈리포트] Next.js 프로젝트에서 도메인 별로 다른 정보 뿌려주기

최근에 진행하는 프로젝트에서 하나의 프로젝트에 여러 도메인을 할당하여 도메인 별로 데이터를 뿌려주기 위한 작업을 진행하였다. 해당 작업을 진행하며 겪었던 이슈와 해결 방법에 대해서 내용을 정리하려고 한다.

 

하나의 프로젝트에서 서로 다른 도메인을 사용한다.

 

그림과 같이 프론트엔드 프로젝트의 로직과 쿼리문은 그대로 유지한 채 뿌려지는 데이터나 메타 데이터, 로고 등만 할당된 도메인에 따라서 보이는 작업을 진행했다.

 

이를 위해 도메인 별로 다르게 표현되어야 하는 부분에서 도메인 정보를 가져오기 위해 현재 주소값에 도메인이 포함되어 있는지를 확인해서 해당 도메인을 리턴해주는 함수를 만들어 사용하였다.

export const getDomain = () => {
    if(typeof window !== "undefined") return "domainA";
    if(window.location.includes("domainA")) return "domainA";
    if(window.location.includes("domainB")) return "domainB";
    return "domainA";
}

 

이 함수는 도메인 별로 상이한 로고를 표현하는 아래와 같은 컴포넌트에서 사용되었다.

import { getDomain } from "./utils";
import VLogo from "./Logo.view";

const Logo: React.FC = () => {
    const domain = getDomain(); // 현재 있는 페이지의 도메인을 할당한다.
    
    return (
        <VLogo src=`./assets/images/${domain}.png` />
    );
}

export default Logo;

 

이렇게 작성했을 때, 문제 없이 domainA로 접속하던, domainB로 접속하던 해당하는 로고 이미지를 얻을 수 있었다. 단, 문제가 있는 부분이 있었는데 바로 메타 데이터이다.

 

도메인 별로 접속했을 때 브라우저의 '검사'(F12키를 통해 확인할 수 있다.) 기능을 통해서 head 태그를 확인해보면 정상적으로 해당 도메인에 설정한 메타 데이터를 확인할 수 있었다. 그렇지만 해당 링크를 보냈을 때 뜨는 메타 데이터는 다른 도메인으로 표시되는 것을 확인할 수 있다. 왜 그렇나면 페이지 소스 보기(홈페이지에서 우클릭 후 해당 메뉴를 눌러 확인할 수 있다.)를 통해 확인할 수 있다. 페이지 소스 보기를 통해 확인해보면 메타 데이터가 우리가 원하는 도메인의 데이터가 아닌 window 객체가 undefined일 때 설정한 도메인인 것을 확인할 수 있다. 즉, 사용자가 확인할 수 있는 메타 데이터와 렌더링된 페이지에서 보이는 메타 데이터의 도메인이 차이가 나는 것이다.

 

(메타 데이터에 대한 간단한 설명은 더보기)

더보기

친구들에게 링크를 보냈을 때, 링크 밑에 이미지와 함께 제목, 설명이 함께 뜨는 것을 본 적이 있을 것이다. 이러한 데이터가 바로 메타 데이터이다. 단순 링크뿐만 아니라 해당 링크에 대한 세부적인 설명을 담을 수 있게 하는 데이터라고 볼 수 있다. 이 메타 데이터가 왜 문제가 되었을까? 그냥 메타 데이터를 렌더링할 때 도메인 별로 분기를 하면 안 되는 것이었을까?

 

이 이슈의 문제는 Next.js의 특징 때문이다. Next.js는 Server Side Rendering(SSR)을 지원하는 React 기반 프레임워크이다. SSR에서는 페이지를 서버에서 빌드한 후 클라이언트에서 확인할 수 있도록 해주는 특징을 갖고 있다. 이 SSR은 페이지를 서버에서 빌드한 후 내려줘야 하기 때문에 첫 로딩이 오래 걸린다는 단점이 있지만, 사용자가 최초 페이지에 접속했을 때 모든 정보를 확인할 수 있다는 장점과 검색 엔진 최적화(SEO_Search Engine Optimization)가 더 좋다는 장점이 있어서 많은 각광을 받고 있다.

 

함수에서 도메인을 가져오기 위해 작성한 함수에서는 window 객체의 현재 url 값에 도메인이 포함되어 있는지를 확인해서 도메인을 반환해주었다. 이 부분이 바로 문제가 된다. 서버는 window 객체를 갖고 있지 않다. 브라우저에서 지원하는 객체이기 때문이다. 서버에서 최초로 빌드될 때는 당연히 window 객체가 undefined일 때 도메인의 메타 데이터로 빌드된 채 배포되게 된다. 따라서 메타 데이터의 도메인이 상이하게 나타나는 것이다.

 

이 이슈를 해결하기 위해서는 코드 단에서는 해결하는 것이 불가능하다.(혹시 방법이 있다면 알려주시면 감사히 배울 수 있도록 하겠다.) 해결하기 위해서는 배포단에서 해결을 해야 한다. 진행 중인 프로젝트는 vercel을 통해서 배포하고 있다. 도메인 별로 상이한 정보의 표현을 위해서 어쩔 수 없이 같은 코드 레포지토리를 기반으로 도메인 별로 vercel 프로젝트를 만들었다. 그리고 환경변수(.env) 파일의 NEXT_PUBLIC_APP_DOMAIN을 정의하여 환경변수 기반으로 도메인 정보를 얻어 빌드할 수 있도록 아래와 같이 함수를 수정하였다.

 

export const getDomain = () => {
    if(!process.env.NEXT_PUBLIC_DOMAIN) return "domainA";
    if(process.env.NEXT_PUBLIC_DOMAIN === "domainA") return "domainA";
    if(process.env.NEXT_PUBLIC_DOMAIN === "domainB") return "domainB";
    return "domainA";
}

 

이를 통해 도메인 별로 빌드 시 서버에서 어떤 도메인인지 확인할 수 있도록 만들었고, 결과적으로 잘 해결되었다.

 


 

SSR이나 SSG(Static Site Generation)은 분명히 일반적으로 React에서 많이 사용하는 CSR(Client Side Rendering)에 비해서 많은 장점을 갖고 있다. 그렇기 때문에 React 18버전에서도 공식적으로 SSR을 지원하는 것이다. 하지만 이런 도메인이나 window 객체를 사용하는 local storage, session strorage를 사용하는 경우에는 코드적이던 배포하는 환경이던 별도의 처리를 필요로 할 수도 있다.

 

오늘도 개발을 할 때 trade-off의 중요성을 다시금 되새기며.. 보다 나은 해법이 있다면 공유해주시면 적용할 수 있도록 하겠다.

반응형