Skip to content

Commit 0c02d84

Browse files
committed
fix: redirect
1 parent 33c1580 commit 0c02d84

5 files changed

Lines changed: 68 additions & 3 deletions

File tree

index.html

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,22 @@
7373
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
7474
<link rel="icon" type="image/x-icon" href="/favicon.ico" />
7575

76+
<!-- GitHub Pages SPA Redirect -->
77+
<script type="text/javascript">
78+
// Single Page Apps for GitHub Pages
79+
// Redirect from query string back to route
80+
(function(l) {
81+
if (l.search[1] === '/' ) {
82+
var decoded = l.search.slice(1).split('&').map(function(s) {
83+
return s.replace(/~and~/g, '&')
84+
}).join('?');
85+
window.history.replaceState(null, null,
86+
l.pathname.slice(0, -1) + decoded + l.hash
87+
);
88+
}
89+
}(window.location))
90+
</script>
91+
7692
<!-- Structured Data -->
7793
<script type="application/ld+json">
7894
{

public/404.html

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="utf-8">
5+
<title>Dev Toolkit</title>
6+
<script type="text/javascript">
7+
// GitHub Pages에서 SPA 라우팅을 위한 리다이렉트
8+
// 404 페이지에서 실제 경로로 리다이렉트
9+
var pathSegmentsToKeep = 0;
10+
var l = window.location;
11+
l.replace(
12+
l.protocol + '//' + l.hostname + (l.port ? ':' + l.port : '') +
13+
l.pathname.split('/').slice(0, 1 + pathSegmentsToKeep).join('/') + '/?/' +
14+
l.pathname.slice(1).split('/').slice(pathSegmentsToKeep).join('/').replace(/&/g, '~and~') +
15+
(l.search ? '&' + l.search.slice(1).replace(/&/g, '~and~') : '') +
16+
l.hash
17+
);
18+
</script>
19+
</head>
20+
<body>
21+
</body>
22+
</html>

public/_redirects

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# SPA Fallback - 모든 경로를 index.html로 리다이렉트
2+
/* /index.html 200
3+
4+
# 특정 파일들은 직접 서빙
5+
/favicon.ico /favicon.ico 200
6+
/robots.txt /robots.txt 200
7+
/sitemap.xml /sitemap.xml 200
8+
/*.png /:splat 200
9+
/*.svg /:splat 200
10+
/*.jpg /:splat 200
11+
/*.jpeg /:splat 200
12+
/*.gif /:splat 200
13+
/*.css /:splat 200
14+
/*.js /:splat 200

src/App.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { Toaster } from "@/components/ui/toaster";
33
import { Toaster as Sonner } from "@/components/ui/sonner";
44
import { TooltipProvider } from "@/components/ui/tooltip";
55
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
6-
import { BrowserRouter, Routes, Route } from "react-router-dom";
6+
import { HashRouter, Routes, Route } from "react-router-dom";
77
import { LanguageProvider } from "@/contexts/LanguageContext";
88
import Index from "./pages/Index";
99
import ToolPage from "./pages/ToolPage";
@@ -17,14 +17,14 @@ const App = () => (
1717
<TooltipProvider>
1818
<Toaster />
1919
<Sonner />
20-
<BrowserRouter>
20+
<HashRouter>
2121
<Routes>
2222
<Route path="/" element={<Index />} />
2323
<Route path="/tools/:toolId" element={<ToolPage />} />
2424
{/* ADD ALL CUSTOM ROUTES ABOVE THE CATCH-ALL "*" ROUTE */}
2525
<Route path="*" element={<NotFound />} />
2626
</Routes>
27-
</BrowserRouter>
27+
</HashRouter>
2828
</TooltipProvider>
2929
</LanguageProvider>
3030
</QueryClientProvider>

vite.config.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,19 @@ export default defineConfig(({ mode }) => ({
99
server: {
1010
host: "::",
1111
port: 8080,
12+
// SPA 라우팅을 위한 히스토리 API 폴백
13+
historyApiFallback: true,
14+
},
15+
build: {
16+
// GitHub Pages를 위한 최적화
17+
rollupOptions: {
18+
output: {
19+
// 청크 파일명 안정화
20+
chunkFileNames: 'assets/[name].[hash].js',
21+
entryFileNames: 'assets/[name].[hash].js',
22+
assetFileNames: 'assets/[name].[hash].[ext]'
23+
}
24+
}
1225
},
1326
plugins: [
1427
react(),

0 commit comments

Comments
 (0)