Skip to content

Instantly share code, notes, and snippets.

@molefrog
Created February 18, 2023 12:54
Show Gist options
  • Save molefrog/70ad57db1acf689b3f4eaf77b7065233 to your computer and use it in GitHub Desktop.
Save molefrog/70ad57db1acf689b3f4eaf77b7065233 to your computer and use it in GitHub Desktop.
wouter@2.10.0 SSR workaround
import { useSyncExternalStore } from "react";
import { navigate } from "wouter/use-location";
/**
* A temporary workaround for wouter@2.10.0 to fix server-side rendering
* Usage (note: the code is the same for client and server)
*
* import { createLocationHookSSR } from "wouter/use-location"
*
* const hook = createLocationHookSSR(url.pathname) // this argument is only used on the server
*
* <Router hook={hook}>Your app!</Router>
*/
interface LocationOptions {
base?: string;
}
/**
* Location hook factory that accepts current path on the server side
*/
export const createLocationHookSSR = (serverSidePath: string) => {
const useCurrentPathnameSSR = () =>
useSyncExternalStore(
subscribeToLocationUpdates,
() => location.pathname,
() => serverSidePath // this was missing
);
return (opts: LocationOptions = {}) => [
relativePath(opts.base, useCurrentPathnameSSR()),
(to, navOpts) => navigate(absolutePath(to, opts.base), navOpts),
];
};
/**
* The following methods are copied from wouter/use-location, there is no way to import them (yet!)
*/
const eventPopstate = "popstate";
const eventPushState = "pushState";
const eventReplaceState = "replaceState";
const eventHashchange = "hashchange";
export const events = [eventPopstate, eventPushState, eventReplaceState, eventHashchange];
const subscribeToLocationUpdates = (callback) => {
for (const event of events) {
addEventListener(event, callback);
}
return () => {
for (const event of events) {
removeEventListener(event, callback);
}
};
};
const relativePath = (base = "", path = location.pathname) =>
!path.toLowerCase().indexOf(base.toLowerCase()) ? path.slice(base.length) || "/" : "~" + path;
const absolutePath = (to, base = "") => (to[0] === "~" ? to.slice(1) : base + to);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment