Custom UI does support it but there’s no information if it would work with UI Kit 2.
Thanks!
Custom UI does support it but there’s no information if it would work with UI Kit 2.
Thanks!
Sorry for bumping an old thread - arrived here via Google since I was also seeking clarification on this topic.
In case this is helpful to others, I followed this guide and despite the focus being Custom UI I can confirm that it worked successfully for my UI Kit 2 app. Here’s the TypeScript code I ended up:
import { view } from "@forge/bridge";
import { useQuery } from "@tanstack/react-query";
import { type JSX, type PropsWithChildren, useEffect, useState } from "react";
import {
type Location,
NavigationType,
type Navigator,
type Path,
Router,
Routes,
createPath,
} from "react-router";
type History = Awaited<ReturnType<typeof view.createHistory>>;
export const HistoryRouter = ({
children,
fallback,
}: PropsWithChildren<{ fallback: JSX.Element }>) => {
const { history, historyState } = useHistory();
if (!history || !historyState) return fallback;
return (
<Router
navigator={getNavigator(history)}
navigationType={getNavigationType(historyState.action)}
location={getLocation(historyState.location)}
>
<Routes>{children}</Routes>
</Router>
);
};
const useHistory = () => {
const { data: history } = useQuery({
queryKey: ["view", "create-history"],
queryFn: view.createHistory,
});
const [historyState, setHistoryState] =
useState<Pick<History, "action" | "location">>();
useEffect(() => {
if (historyState || !history) return;
setHistoryState({ action: history.action, location: history.location });
}, [history, historyState]);
useEffect(() => {
if (!history) return;
history.listen((location, action) => {
setHistoryState({ action, location });
});
}, [history]);
return { history, historyState };
};
const getNavigator = (history: History): Navigator => ({
createHref: (to: string | Partial<Path>) =>
typeof to === "string" ? to : createPath(to),
go: history.go,
push: history.push,
replace: history.replace,
});
const getNavigationType = (action: History["action"]) => {
switch (action) {
case "POP":
return NavigationType.Pop;
case "PUSH":
return NavigationType.Push;
case "REPLACE":
return NavigationType.Replace;
}
};
const getLocation = (location: History["location"]): Partial<Location> => {
const { key, ...rest } = location;
return key !== undefined ? { ...rest, key } : rest;
};
which can be used like so:
<HistoryRouter fallback={<Spinner />}>
<Route index element={<Home />} />
<Route path="test" element={<Test />} />
</HistoryRouter>