Ann's log

[React] Github Pages๋กœ ๋ฐฐํฌํ•˜๊ณ  ์ƒˆ๋กœ๊ณ ์นจ์‹œ 404 ์—๋Ÿฌ ํ•ด๊ฒฐ ๋ณธ๋ฌธ

React

[React] Github Pages๋กœ ๋ฐฐํฌํ•˜๊ณ  ์ƒˆ๋กœ๊ณ ์นจ์‹œ 404 ์—๋Ÿฌ ํ•ด๊ฒฐ

-Ann- 2022. 5. 30. 17:57

 

404 ํŽ˜์ด์ง€

 

 

๐Ÿ˜ฑ  ๋ฌธ์ œ

GitHub Pages๋กœ ๋ฐฐํฌํ•œ React ํŽ˜์ด์ง€์—์„œ ์ƒˆ๋กœ๊ณ ์นจ์„ ํ•˜๋ฉด 404 ์—๋Ÿฌ๊ฐ€ ๋œฌ๋‹ค๋Š” ๊ฒƒ์„ ๋ฐœ๊ฒฌํ–ˆ๋‹ค.

Homepage์—์„œ๋Š” ์ƒˆ๋กœ๊ณ ์นจํ•ด๋„ ์•„๋ฌด๋Ÿฐ ๋ฌธ์ œ๊ฐ€ ์—†๋Š”๋ฐ, ์„œ๋ธŒ ๋””๋ ‰ํ† ๋ฆฌ๋กœ ์ด๋™ํ•˜๊ณ  ์ƒˆ๋กœ๊ณ ์นจ์„ ํ•˜๋ฉด ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค..

 

์ด์œ ๋ฅผ ์ฐพ์•„๋ณด๋‹ˆ ๊นƒํ—ˆ๋ธŒ ํŽ˜์ด์ง€๋Š” SPA(Single Page Applications)๋ฅผ ์ธ์‹ํ•˜์ง€ ๋ชปํ•˜๋Š” ๋ฌธ์ œ๊ฐ€ ์žˆ๋‹ค๊ณ  ํ•œ๋‹ค!

SPA๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ ์›น ๋ธŒ๋ผ์šฐ์ €์—์„œ ์•ก์„ธ์Šค ํ•  ์ˆ˜ ์žˆ๋Š” ํ•˜๋‚˜์˜ index.html ํŒŒ์ผ๋งŒ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์—, Github Pages๋กœ ๋ฐฐํฌ๋ฅผ ํ•˜๊ฒŒ ๋˜๋ฉด homepage url ํ•˜๋‚˜๋งŒ ์ธ์‹ํ•˜๊ฒŒ ๋œ๋‹ค.

๊ทธ๋ž˜์„œ hompage url ๋’ค์— ๊ฒฝ๋กœ๊ฐ€ ๋” ๋ถ™์œผ๋ฉด ๊ทธ ๊ฒฝ๋กœ์—์„œ ํ•ด๋‹น ํŽ˜์ด์ง€์˜ ํŒŒ์ผ์„ ์ฐพ์œผ๋ ค ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜๊ฒŒ ๋œ๋‹ค.

 

 

๐Ÿ˜„  ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•

๊ตฌ๊ธ€์— ๊ฒ€์ƒ‰ํ•ด ๋ณด๋‹ˆ๊นŒ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์€ ์—ฌ๋Ÿฌ ๊ฐ€์ง€๊ฐ€ ์žˆ๋Š” ๊ฒƒ ๊ฐ™๋‹ค.

Create React App ๋ฌธ์„œ์—์„œ๋Š” 2๊ฐ€์ง€ ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ์•Œ๋ ค์ฃผ๊ณ  ์žˆ๋Š”๋ฐ, ๋‚˜๋Š” 404.html์„ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์จ๋ณด๋ ค ํ•œ๋‹ค.

 

 

404.html์„ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•

CRA ๋ฌธ์„œ์—์„œ๋Š” spa-github-pages ๊ฐ€์ด๋“œ๋ฅผ ์ฐธ๊ณ ํ•˜๋ผ๊ณ  ๋‚˜์™€์žˆ๋‹ค.

(์ด ๊ธ€์„ ํ•œ๊ตญ์–ด๋กœ ๋ฒˆ์—ญํ•ด ์ฃผ์‹  ๊นƒํ—ˆ๋ธŒ ์ €์žฅ์†Œ๊ฐ€ ์žˆ์–ด์„œ ์ด ๊ธ€์„ ์ฐธ๊ณ ํ•˜์˜€๋‹ค.)

 

์ด ๋ฐฉ๋ฒ•์€ ์•Œ ์ˆ˜ ์—†๋Š” ๊ฒฝ๋กœ์—์„œ๋Š” 404.html ํŽ˜์ด์ง€๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์ด์šฉํ•˜์—ฌ 404 ํŽ˜์ด์ง€๋ฅผ ์šฐํšŒํ•˜๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค.

404.html ํŒŒ์ผ์— ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์ž‘์„ฑํ•ด์„œ query์™€ hash๋กœ ๊ตฌ์„ฑ๋œ ์ƒˆ๋กœ์šด URL์„ ๋ฐ˜ํ™˜ํ•˜์—ฌ redirectionํ•˜๊ฒŒ ๋œ๋‹ค.

๋งŒ์•ฝ์— URL์ด example.tld/one/two?a=b&c=d#qwe์ธ ๊ฒฝ์šฐ, example.tld/?p=/one/two&q=a=b~and~c=d#qwe๋กœ ๋ณ€๊ฒฝ๋œ๋‹ค๊ณ  ํ•œ๋‹ค.

 

public/404.html

1. React ํ”„๋กœ์ ํŠธ ํด๋”์˜ public ํด๋” ์•ˆ์— 404.html ํŒŒ์ผ์„ ์ƒ์„ฑํ•œ๋‹ค.

2. ๋‹ค์Œ ๋‚ด์šฉ์„ ๊ทธ๋Œ€๋กœ ๋ณต์‚ฌํ•ด์„œ ๋ถ™์—ฌ ๋„ฃ๋Š”๋‹ค.

(์ถœ์ฒ˜: https://github.com/rafgraph/spa-github-pages/blob/gh-pages/404.html)

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Single Page Apps for GitHub Pages</title>
    <script type="text/javascript">
      // Single Page Apps for GitHub Pages
      // MIT License
      // https://github.com/rafgraph/spa-github-pages
      // This script takes the current url and converts the path and query
      // string into just a query string, and then redirects the browser
      // to the new url with only a query string and hash fragment,
      // e.g. https://www.foo.tld/one/two?a=b&c=d#qwe, becomes
      // https://www.foo.tld/?/one/two&a=b~and~c=d#qwe
      // Note: this 404.html file must be at least 512 bytes for it to work
      // with Internet Explorer (it is currently > 512 bytes)

      // If you're creating a Project Pages site and NOT using a custom domain,
      // then set pathSegmentsToKeep to 1 (enterprise users may need to set it to > 1).
      // This way the code will only replace the route part of the path, and not
      // the real directory in which the app resides, for example:
      // https://username.github.io/repo-name/one/two?a=b&c=d#qwe becomes
      // https://username.github.io/repo-name/?/one/two&a=b~and~c=d#qwe
      // Otherwise, leave pathSegmentsToKeep as 0.
      var pathSegmentsToKeep = 0;

      var l = window.location;
      l.replace(
        l.protocol + '//' + l.hostname + (l.port ? ':' + l.port : '') +
        l.pathname.split('/').slice(0, 1 + pathSegmentsToKeep).join('/') + '/?/' +
        l.pathname.slice(1).split('/').slice(pathSegmentsToKeep).join('/').replace(/&/g, '~and~') +
        (l.search ? '&' + l.search.slice(1).replace(/&/g, '~and~') : '') +
        l.hash
      );

    </script>
  </head>
  <body>
  </body>
</html>

 

์ด ํŒŒ์ผ์€ 404.html์ด ๋ฐ˜ํ™˜๋  ๋•Œ ํ˜„์žฌ URL์„ ์ƒˆ๋กœ์šด URL๋กœ ๋ณ€๊ฒฝ์‹œํ‚ค๊ณ  ๋ธŒ๋ผ์šฐ์ €๋ฅผ redirect ํ•ด์ฃผ๋Š” script๋ฅผ ํฌํ•จํ•˜๊ณ  ์žˆ๋‹ค.

๋งŒ์•ฝ ์ปค์Šคํ…€ ๋„๋ฉ”์ธ์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  username.github.io/repo-name ํ˜•์‹์˜ ์ฃผ์†Œ๋ฅผ ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ, pathSegmentsToKeep ๋ณ€์ˆ˜์˜ ๊ฐ’์€ 0์ด ์•„๋‹Œ 1๋กœ ๋ฐ”๊ฟ”์ค˜์•ผ ํ•œ๋‹ค!

 

 

public/index.html

1. public ํด๋” ์•ˆ์˜ index.html ํŒŒ์ผ์˜ </head> ํƒœ๊ทธ ๋ฐ”๋กœ ์ „์— ๋‹ค์Œ ๋‚ด์šฉ์„ ์ถ”๊ฐ€ํ•œ๋‹ค.

(์ถœ์ฒ˜: https://github.com/rafgraph/spa-github-pages/blob/gh-pages/index.html#L58)

<!-- Start Single Page Apps for GitHub Pages -->
    <script type="text/javascript">
      // Single Page Apps for GitHub Pages
      // MIT License
      // https://github.com/rafgraph/spa-github-pages
      // This script checks to see if a redirect is present in the query string,
      // converts it back into the correct url and adds it to the
      // browser's history using window.history.replaceState(...),
      // which won't cause the browser to attempt to load the new url.
      // When the single page app is loaded further down in this file,
      // the correct url will be waiting in the browser's history for
      // the single page app to route accordingly.
      (function(l) {
        if (l.search[1] === '/' ) {
          var decoded = l.search.slice(1).split('&').map(function(s) { 
            return s.replace(/~and~/g, '&')
          }).join('?');
          window.history.replaceState(null, null,
              l.pathname.slice(0, -1) + decoded + l.hash
          );
        }
      }(window.location))
    </script>
    <!-- End Single Page Apps for GitHub Pages -->

 

์ด script๋Š” ์ฟผ๋ฆฌ ์ŠคํŠธ๋ง์— ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ๊ฐ€ ์กด์žฌํ•˜๋Š”์ง€ ํ™•์ธํ•ด์„œ ๋‹ค์‹œ ์˜ฌ๋ฐ”๋ฅธ URL๋กœ ๋ณ€ํ™˜์‹œํ‚ค๋Š” ์—ญํ• ์„ ํ•œ๋‹ค.

๊ทธ๋ฆฌ๊ณ  window.history.replaceState()๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ธŒ๋ผ์šฐ์ € ํžˆ์Šคํ† ๋ฆฌ์— ์ถ”๊ฐ€ํ•˜๊ฒŒ ๋˜๋Š”๋ฐ, ๋ธŒ๋ผ์šฐ์ €๋Š” ์ƒˆ๋กœ์šด URL์„ ๋กœ๋“œํ•˜์ง€๋Š” ์•Š๋Š”๋‹ค๊ณ  ํ•œ๋‹ค.

MDN ๋ฌธ์„œ๋ฅผ ์ฐพ์•„๋ณด๋‹ˆ, replaceState()๋ฅผ ์‚ฌ์šฉํ•˜๊ฒŒ ๋˜๋ฉด URL ํ‘œ์‹œ์ค„์—๋Š” ์ƒˆ๋กœ์šด URL์ด ํ‘œ์‹œ ๋˜์ง€๋งŒ, ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ๊ทธ ํŒŒ์ผ์ด ์žˆ๋Š”์ง€ ํ™•์ธํ•˜์ง€๋Š” ์•Š๋Š”๋‹ค๊ณ  ํ•œ๋‹ค.

 

2. ํ”„๋กœ์ ํŠธ๋ฅผ Github Pages๋กœ ์žฌ๋ฐฐํฌ ํ•œ๋‹ค.

 

ํ…Œ์ŠคํŠธ ํ•ด๋ณด๋‹ˆ๊นŒ ์ด์ œ๋Š” ์ƒˆ๋กœ๊ณ ์นจ ํ•ด๋„ 404 ํŽ˜์ด์ง€๊ฐ€ ๋ณด์ด์ง€ ์•Š๊ณ  ์ •์ƒ์ ์œผ๋กœ ์ž‘๋™ํ•˜๊ฒŒ ๋˜์—ˆ๋‹ค!! ๐Ÿ˜†

๋น„๋ก ๋‚ด๊ฐ€ ์ง์ ‘ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด์„œ ํ•ด๊ฒฐํ•œ๊ฑด ์•„๋‹ˆ์ง€๋งŒ, ์ด๋ฒˆ์— ์‚ฌ์šฉํ•œ ์ฝ”๋“œ์— ๋Œ€ํ•ด ๊ณต๋ถ€ํ•ด์„œ ๋‚˜์ค‘์— ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด๋ด์•ผ๊ฒ ๋‹ค.

 

 


์ฐธ๊ณ :

https://velog.io/@superstardanwoo/SPA%EC%97%90%EC%84%9C-%EB%92%A4%EB%A1%9C%EA%B0%80%EA%B8%B0-%EC%83%88%EB%A1%9C%EA%B3%A0%EC%B9%A8-%EC%8B%9C-404-Not-Found-%EC%98%A4%EB%A5%98-%ED%95%B4%EA%B2%B0

https://chinsun9.github.io/2021/07/30/serve-react-app-simply/

Comments