[Next.js] NextJS에서 subdomain 처리하기

hyeonQyu·2022년 6월 29일
5
post-thumbnail

NextJS를 사용하여 프로젝트를 진행하던 도중 도메인이 결정되었고 서브도메인을 사용하게 되었습니다.
생각지도 못하게 서브 도메인이 붙어서 NextJS를 이제 막 사용해보기 시작한 저로서는 매우 당황스러웠습니다.

서브도메인

서브도메인이란 DNS 계층에서 주 도메인을 보조하는 도메인입니다. 우리가 흔히 사용하는 네이버를 예로 들어보면

  • 블로그: blog.naver.com
  • 메일: mail.naver.com
  • 쇼핑: shopping.naver.com

에서 굵게 표시된 부분으로 서브도메인을 통해 다른 서비스에 사용자가 접근할 수 있죠.

NextJS 라우팅

NextJS에서는 pages 디렉토리 내 폴더 및 파일 이름대로 라우팅됩니다.
즉 디렉토리 구조가 아래와 같이 구성되어 있고 사용하는 도메인이 hyeonqyu.com 이라고 한다면
📂pages
   📂members
       🗒️index.tsx
       🗒️login.tsx
   📂accounts
       🗒️index.tsx
       🗒️user.tsx

hyeonqyu.com/members
hyeonqyu.com/members/login
hyeonqyu.com/accounts
hyeonqyu.com/accounts/user
와 같은 URL로 페이지에 접근할 수 있을 거에요.

NextJS에서 서브도메인 적용

고민

그러나 해야 하는 것은
hyeonqyu.com/members
hyeonqyu.com/members/login
hyeonqyu.com/accounts
hyeonqyu.com/accounts/user
이 URL이 아니라
members.hyeonqyu.com
members.hyeonqyu.com/login
accounts.hyeonqyu.com
accounts.hyeonqyu.com/user 이 URL이었습니다.
그러나 NextJS의 pages 폴더만으로는 이처럼 구현할 수 없었죠.

그래서 서브도메인마다 각각 다른 NextJS 앱을 구동시켜야 하는건가 하는 생각이 들었지만 서브도메인 하나하나가 그렇게 덩치가 크지 않음에도 불구하고 여러 서버를 띄우면 그만큼 서버 비용도 늘어나고.. 관리해야 할 프로젝트도 늘어나기에..
하나의 앱으로 여러 서브도메인에 라우팅할 수 있도록 만드는 것이 베스트였습니다.

커스텀 server.js 작성

열심히 구글링한 결과 https://github.com/dcangulo/nextjs-subdomain-example 이 레포지토리를 찾을 수 있었습니다.
먼저 package.json의 script 부분을 보면 아래와 같이 되어있는 것을 볼 수 있습니다.

"dev": "node server.js",
"build": "next build",
"start": "NODE_ENV=production node server.js"

일반적으로 create next app으로 프로젝트를 생성하면 devnext dev, startnext start로 작성되어 있지만 여기서는 node server.js로 작성되어 있습니다.

루트에 커스텀 서버 스크립트인 server.js가 있는데 여기를 수정하면 원하는대로 서브도메인을 사용할 수 있었습니다.

const express = require('express');
const next = require('next');

const port = process.env.PORT || 3000;
const app = next({ dev: process.env.NODE_ENV !== 'production' });

이 server.js에서 next를 실행시키는 것으로 보이는군요.

app.prepare().then(() => {
    const mainServer = express();

    const membersServer = express();
    const accountsServer = express();
  	...
});

다음으로
members.hyeonqyu.com
accounts.hyeonqyu.com
이렇게 두개의 서브도메인을 사용하기 위해서 express 서버를 3개 만듭니다.

membersServermembers 서브도메인, accountsServeraccounts 서브 도메인을 위해 생성했어요.

app.prepare().then(() => {
    ...
    membersServer.get('/', (req, res) => {
        return app.render(req, res, '/members', req.query);
    });

    membersServer.get('/*', (req, res) => {
        return app.render(req, res, `/members${req.path}`, req.query);
    });

    membersServer.all('*', (req, res) => {
        return handle(req, res);
    });

    accountsServer.get('/', (req, res) => {
        return app.render(req, res, '/accounts', req.query);
    });

    accountsServer.get('/*', (req, res) => {
        return app.render(req, res, `/accounts${req.path}`, req.query);
    });

    accountsServer.all('*', (req, res) => {
        return handle(req, res);
    });
});

membersServer에 들어오는 요청은 /members 하위 페이지를 렌더링하고 accountsServer에 들어오는 요청은 /accounts 하위 페이지를 렌더링하도록 합니다.

app.prepare().then(() => {
  	...
    mainServer.use(vhost('members.midasuser.com', membersServer));
    mainServer.use(vhost('accounts.midasuser.com', accountsServer));

    mainServer.listen(port, (err) => {
        if (err) {
            throw err;
        }
    });
});

가상호스트 라이브러리인 vhost를 사용해 서브도메인을 등록해주면 됩니다.

hosts 파일 수정

서브도메인이 잘 적용되었는지 로컬에서 확인해보려면 hosts파일을 수정해야해요.
hosts 파일은 C:\Windows\System32\drivers\etc에 있으며 파일을 열어 다음 내용을 추가합니다.

127.0.0.1 members.hyeonqyu.com
127.0.0.1 accounts.hyeonqyu.com

서브도메인 적용 확인

npm run dev로 앱을 실행하여 members.hyeonqyu.com:3000에 접속합니다.
/members/index.tsx(jsx) 파일에 작성한 내용이 렌더링된다면 성공적으로 적용된 것입니다.

profile
백엔드가 하고 싶었던 프론트엔드 개발자

0개의 댓글