feat: add catch-all route for direct board slug URLs

Added routes to handle direct slug URLs like canvas.jeffemmett.com/ccc
These now redirect to /board/ccc/ to maintain backward compatibility
with old links from jeffemmett.com/board/ccc

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Jeff Emmett 2026-01-02 18:14:05 +01:00
parent 33fa5c9395
commit 95d7f9631c
1 changed files with 30 additions and 10 deletions

View File

@ -28,6 +28,9 @@ import { ErrorBoundary } from './components/ErrorBoundary';
import CryptID from './components/auth/CryptID';
import CryptoDebug from './components/auth/CryptoDebug';
// Import Web3 provider for wallet integration
import { Web3Provider } from './providers/Web3Provider';
// Import Google Data test component
import { GoogleDataTest } from './components/GoogleDataTest';
@ -116,6 +119,15 @@ const RedirectBoardSlug = () => {
return <Navigate to={`/board/${slug}/`} replace />;
};
/**
* Component to redirect direct slug URLs to board URLs
* Handles canvas.jeffemmett.com/ccc /board/ccc/
*/
const RedirectDirectSlug = () => {
const { slug } = useParams<{ slug: string }>();
return <Navigate to={`/board/${slug}/`} replace />;
};
/**
* Main App with context providers
*/
@ -142,11 +154,12 @@ const AppWithProviders = () => {
return (
<ErrorBoundary>
<AuthProvider>
<FileSystemProvider>
<NotificationProvider>
<Suspense fallback={<LoadingSpinner />}>
<DailyProvider callObject={null}>
<BrowserRouter>
<Web3Provider>
<FileSystemProvider>
<NotificationProvider>
<Suspense fallback={<LoadingSpinner />}>
<DailyProvider callObject={null}>
<BrowserRouter>
{/* Display notifications */}
<NotificationsDisplay />
@ -209,13 +222,20 @@ const AppWithProviders = () => {
{/* Google Data routes */}
<Route path="/google" element={<GoogleDataTest />} />
<Route path="/oauth/google/callback" element={<GoogleDataTest />} />
{/* Catch-all: Direct slug URLs redirect to board URLs */}
{/* e.g., canvas.jeffemmett.com/ccc → /board/ccc/ */}
{/* Must be LAST to not interfere with other routes */}
<Route path="/:slug" element={<RedirectDirectSlug />} />
<Route path="/:slug/" element={<RedirectDirectSlug />} />
</Routes>
</Suspense>
</BrowserRouter>
</DailyProvider>
</Suspense>
</NotificationProvider>
</FileSystemProvider>
</BrowserRouter>
</DailyProvider>
</Suspense>
</NotificationProvider>
</FileSystemProvider>
</Web3Provider>
</AuthProvider>
</ErrorBoundary>
);