FrameWorks/Vue

VueRouter의 Diffrenet History Modes 파헤치기

ABCD 2024. 6. 26.

다양한 히스토리 모드

Vue Router Instance에는 생성할 때, history 옵션을 사용하여 다양한 히스토리 모드 중 하나를 선택해서 적용할 수 있습니다.

Hash Mode

createWebHashHistory()를 사용하여 설정합니다.

https://example.com/#/user/id와 같은 모습

 

내부적으로 사용하는 URL 앞에 해시 문자(#)를 사용합니다.
URL의 이 섹션은 서버로 전달되지 않으므로 특별한 조치가 필요하지 않으나, SEO에 나쁜 영향을 미치므로 이것이 문제가 된다면 HTML5 모드를 사용해야 합니다.

import { createRouter, createWebHashHistory } from 'vue-router'

const router = creatgeRouter({
    history: createWebHashHistory(),
    routes: [
        // ...
    ],
})

HTML5 Mode

createWebHistory()를 사용하여 설정하며, 권장하는 모드입니다.

https://example.com/user/id와 같은 모습

HTML5 모드에서는 정상적인 URL의 형태를 갖습니다.
하지만, 여기에는 여러가지 문제가 발생하는데, Vue의 경우 적절한 서버 구성이 없는 클라이언트 사이드 SPA이므로, 사용자가 브라우저에서 바로 https://example.com/user/id로 접속하면 404오류가 발생합니다.

 

따라서 서버에 간단한 라우팅을 설정하여 URL 접근이 배포된 정적 자산과 일치하지 않으면, 앱의 index.html 페이지를 제공하도록 해야합니다.

 

예를 들면 Nginx를 사용하여 location을 설정할 때 try_files를 index.html로 설정해주는 것이 그 이유입니다.

import { createRouter, createWebHistory } from 'vue-router'

const router = creatgeRouter({
    history: createWebHistory(),
    routes: [
        // ...
    ],
})

Memory Mode

createMemoryHistory()를 사용하여 설정합니다.
메모리 모드는 브라우저 환경을 고려하지 않습니다. 따라서 URL과 상호작용하지 않으며, 자동으로 네비게이션 초기화를 트리거하지 않습니다.


Memory Mode의 경우 Node.js환경의 SSR에 완벽합니다.
app.use(router)를 호출 후 반드시 네비게이션 초기화를 해야합니다.

브라우저에서 이 모드를 사용할 수 있지만, 히스토리가 없으므로 권장되지는 않습니다.
뒤로 or 앞으로 이동할수가 없기 때문이죠.

import { createRouter, createMemoryHistory } from 'vue-router'

const router = creatgeRouter({
    history: createMemoryHistory(),
    routes: [
        // ...
    ],
})

서버 구성 예제

참고: 아래 예제들은 루트 폴더에서 앱을 제공한다고 가정합니다. 루트 폴더 대신 하위 폴더에 배포하는 경우, Vue CLI의 publicPath 옵션라우터의 base 속성을 설정해야 합니다. 또한 예제를 조정해야 합니다(예: RewriteBase /RewriteBase /name-of-your-subfolder/로 교체).

Apache

<IfModule mod_negotiation.c>
    Options -MultiViews
</IfModule>

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /
    RewriteRule ^index\.html$ - [L]
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule . /index.html [L]
</IfModule>

 

mod_rewrite 대신 FallbackResource를 사용할 수도 있습니다.

nginx

location / {
    try_files $uri $uri/ /index.html;
}

네이티브 Node.js

const http = require('http')
const fs = require('fs')
const httpPort = 80

http
    .createServer((req, res) => {
        fs.readFile('index.html', 'utf-8', (err, content) => {
            if (err) {
                console.log('"index.html" 파일을 열 수 없습니다.')
            }

            res.writeHead(200, {
                'Content-Type': 'text/html; charset=utf-8',
            })

            res.end(content)
        })
    })
    .listen(httpPort, () => {
        console.log('서버 수신 대기 중: http://localhost:%s', httpPort)
    })

Node.js에서 Express

Node.js의 Express 경우, connect-history-api-fallback 미들웨어 사용을 고려하십시오.

Internet Information Services (IIS)

  1. IIS UrlRewrite 설치
  2. 다음을 사용하여 사이트의 루트 디렉터리에 web.config 파일을 만듭니다:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
        <rewrite>
            <rules>
                <rule name="Handle History Mode and custom 404/500" stopProcessing="true">
                <match url="(.*)" />
                <conditions logicalGrouping="MatchAll">
                    <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
                    <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
                </conditions>
                <action type="Rewrite" url="/" />
                </rule>
            </rules>
        </rewrite>
    </system.webServer>
</configuration>

Caddy v2

try_files {path} /

Caddy v1

rewrite {
    regexp .*
    to {path} /
}

Firebase hosting

firebase.json의 호스팅 부분을 다음과 같이 수정:

{
    "hosting": {
        "public": "dist",
        "rewrites": [
            {
                "source": "**",
                "destination": "/index.html"
            }
        ]
    }
}

Netlify

_redirects 파일을 만들어 배포될 파일에 포함:

/* /index.html 200

vue-cli, nuxt 및 vite 프로젝트에서 이 파일은 일반적으로 static 또는 public이라는 폴더에 있습니다.

Netlify 문서에서 문법에 대해 자세히 알아볼 수 있습니다. 리다이렉션을 다른 Netlify 기능과 결합하기 위해 netlify.toml을 생성할 수도 있습니다.

Vercel

프로젝트의 루트 디렉터리에 다음과 같은 vercel.json 파일을 만듭니다:

{
    "rewrites": [
        { "source": "/:path*", "destination": "/index.html" }
    ]
}

경고

Vue Router를 사용하여 만든 클라이언트 사이드 SPA는 모든 라우트에 index.html을 제공하므로, 서버는 더 이상 찾을 수 없는 페이지에 대해서 404 오류를 반환하지 않습니다. 이 문제를 해결하려면, 정의되지 않은 모든 라우트르 포괄할 수 있는 "포괄 라우트"를 구현하여, 404 페이지를 표시해야 합니다.

const router = createRouter({
    history: createWebHistory(),
    routes: [
        { path: '/:pathMatch(.*)', component: NotFoundComponent }
    ],
})

 

또는 Node.js 서버를 사용하는 경우, 서버 측 라우터를 사용하여 수신되는 URL을 매칭하고, 매칭되는 라우트가 없으면 404로 응답하는 폴백을 구현할 수 있습니다. 자세한 내용 참고: Vue SSR 문서

728x90
반응형

댓글

💲 추천 글