HashRouter.jsxjavascript
import { HashRouter, Routes, Route } from "react-router";
import Pages from "./Routes";
import { ContentProvider } from "./services/content";
import { ScreensaverProvider } from "./services/screensaver";
import { Screensaver } from "./components/Screensaver/Screensaver";
import { ErrorBoundary } from "./components/ErrorBoundary";
import { Stage } from "./components/Stage/Stage";
import { PrintMapPage } from "./pages/PrintMap/PrintMap";
/**
* Hash-based router variant - works regardless of the deploy path, so it's
* the default (see App.jsx). Stage (the whole-app scale wrapper, see
* Stage.jsx) sits inside <HashRouter> rather than around it in App.jsx,
* because it reads its config via useConfig() -> useSearchParams(), which
* requires router context. Content + screensaver providers around the
* routes, pages guarded by the ErrorBoundary; the Screensaver stays mounted
* as a sibling so its fade works in both directions.
*
* `/print-map` is a dev-only export tool (see PrintMap.jsx), not part of the
* visitor-facing kiosk - it's branched out here, before Stage/ContentProvider/
* ScreensaverProvider, so it gets none of the kiosk chrome (fixed-resolution
* scaling, idle screensaver) and fetches its own content directly instead of
* going through ContentProvider's route-based file resolution
* (presentationModes.js has no entry for it).
*/
const Router = () => {
return (
<HashRouter>
<Routes>
<Route path="/print-map" element={<PrintMapPage />} />
<Route
path="/*"
element={
<Stage>
<ContentProvider>
<ScreensaverProvider>
<ErrorBoundary>
<Pages />
</ErrorBoundary>
<Screensaver />
</ScreensaverProvider>
</ContentProvider>
</Stage>
}
/>
</Routes>
</HashRouter>
);
};
export default Router;