Skip to content

docs: Migrate to tanstack router#2895

Merged
MichaelParadis merged 34 commits intomasterfrom
MIKE/migrate-to-tanstack-router
Mar 12, 2026
Merged

docs: Migrate to tanstack router#2895
MichaelParadis merged 34 commits intomasterfrom
MIKE/migrate-to-tanstack-router

Conversation

@MichaelParadis
Copy link
Copy Markdown
Contributor

@MichaelParadis MichaelParadis commented Feb 2, 2026

Motivations

There are some improvements we want to make to the doc site such as linking directly to tabs and using hashes to link directly to headings. While react-router-dom supports this type of stuff we are currently using a super old version (react router dom v5 which was last updated 2 years ago). Since it was such an old version finding resources for this version would be difficult.

In theory I could have updated react-router-dom on the docs site, however I decided to migrate to tanstack router for the following reasons:

  1. There was a ticket to migrate to tanstack router https://jobber.atlassian.net/browse/JOB-111826
  2. TSR is the library we use in other repos

Future work

Adding support for copying and going to headings in other tabs (for example the implement tab)

Changes

  • Migration from react-router-dom to tanstack router. Mostly handled by cursor.
  • Use tanstack router path params for the following:
    1. Tab to display (web, mobile and implement)
    2. Component name for the docs
  • Used tanstack router search params for
    1. Determining if the legacy or v2 versions of components should be shown
    2. Determining if the minimal version of the site should be used
  • Added mdx plugins for generating the table of contents for the design tab
  • Added support for copying the link to h2s on the design tab
  • Unified checks related to the url to leverage tanstack router instead of mixing between react router dom and vanilla JS
  • Simplified how routes are generated

Added

  • Added ability to link to the tabs on a component
  • Added ability to link to h2 on a docs page

Changed

Deprecated

Removed

Fixed

Security

Testing

  • Verify that you can copy links to components and the respective tabs in them.
  • Verify that you can link between the legacy and supported versions of components
  • Verify that you can copy links to h2s on the design tab of components
  • Verify that the side navigation will navigate you between tabs and to the headings when viewing a component. For example while on the Button component in the implement tab when you click "variants" it takes you to the design tab and scrolls to that heading

Changes can be
tested via Pre-release


In Atlantis we use Github's built in pull request reviews.

@cloudflare-workers-and-pages
Copy link
Copy Markdown

cloudflare-workers-and-pages Bot commented Feb 2, 2026

Deploying atlantis with  Cloudflare Pages  Cloudflare Pages

Latest commit: 2a8795f
Status: ✅  Deploy successful!
Preview URL: https://f5f05ebd.atlantis.pages.dev
Branch Preview URL: https://mike-migrate-to-tanstack-rou.atlantis.pages.dev

View logs


useEffect(() => {
if (code) {
console.log("updating code");
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove this

@MichaelParadis MichaelParadis marked this pull request as ready for review March 11, 2026 16:17
@MichaelParadis MichaelParadis requested a review from a team as a code owner March 11, 2026 16:17
Copy link
Copy Markdown
Contributor

@scotttjob scotttjob left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Smoke tested locally. Can't find any major issues.

This is overall a low-risk PR because it shouldn't affect the build output of the product. Michael if you can run a diff output and confirm the build is identical, then I saw we just ship it (I'll come back and approve).

Overall there's some chunky code in places, just in terms of length, but we're doing a fair amount of complex functionality in here. We can continue to iterate once react-router is out properly.

label: string;
}

export type RecmaVFile = VFile & {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is a Recma?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is a JS processor for markdown files for writing plugins with mdx files
https://github.com/mdx-js/recma

import { Box, Content, Typography } from "@jobber/components";
import { MouseEvent, useEffect, useState } from "react";
import { Link, useMatches, useParams } from "@tanstack/react-router";
import omit from "lodash/omit";
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have a polite, module bundler friendly related request. Is there any way we can avoid lodash usage moving forward?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nuked in a23f7b6

* Recma plugin: injects `export const toc = [...]` from file.data.toc so the
* compiled MDX module exports a TOC for the sidebar.
*/
export function recmaInjectToc() {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd love some more detailed JS Doc comments in here explaining what some of this code is up, and why. May help future us/LLMs.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a few more comments in 190e05c I totally lost my initial references for this

}, 100);
}
};
const newParams = omit(params, "tab");
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just so I'm not all "no way lodash" without any support as how to work without lodash omit, In this case, I know it's a little clunky but it doesn't require any libraries:

const newParams = { ...params };
delete newParams.tab;

The other solution {tab:_tab, ...newParams} = params doesn't work for us because we lint away unused variables, so the delete is the backup.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can nuke lodash. I tried doing the import of lodash to help with tree shaking but I can nuke it. I used import omit from "lodash/omit" instead of the heavier import { omit } from "lodash"

* This isn't really a Layout component, but it's not really a component component either. We could make a "Views" directory maybe, or a "Template" directory?
* @returns ReactNode
*/
// eslint-disable-next-line max-statements
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:that-thing-you-do-with-your-fingers-that-sounds-like-a-snap-rainbow:

[PageMeta, currentPlatform],
);

// Set initial type based on what's available for this component
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:that-thing-you-do-with-your-fingers-that-sounds-like-a-snap-rainbow:

}
}, [code, type, updateCode]);

const handleTabChange = (tabIn: number) => {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:that-thing-you-do-with-your-fingers-that-sounds-like-a-snap-rainbow:

import UseResizeObserverDocs from "../content/hooks/useResizeObserver.stories.mdx";
import UseStepperDocs from "../content/hooks/useStepper.stories.mdx";
import UseWindowDimensionsDocs from "../content/hooks/useWindowDimensions.stories.mdx";
import UseBoolDocs, {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All this extra boilerplate...I really want to find a better solve for this long-term. It's not the worst, but it's not great either.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I do want to remove the boiler plate on this. I was original going to migrate to file based routing in TSR but that made things chunky and I figured getting to TSR was a good first step

{
path: "/guides",
handle: "Guides",
exact: true,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yessssss

"react-element-to-jsx-string": "^15.0.0",
"react-markdown": "^10.1.0",
"react-native-svg-web": "^1.0.9",
"react-router": "5.3.4",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yayayaya

@MichaelParadis
Copy link
Copy Markdown
Contributor Author

@scotttjob I just pushed a fix in 2a8795f which solves a problem I just found where if you clicked on a mobile usage or props link on the sidebar it wouldn't actually go to the mobile tab and would instead stay on web (or whatever platform you were currently on)

@taylorvnoj
Copy link
Copy Markdown
Contributor

I am QA-ing 👀

Copy link
Copy Markdown
Contributor

@taylorvnoj taylorvnoj left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

big improvement! sooo excited about the linking! All the QA items you listed work as described.

I see Scott reviewed also and dug deeper into the code than I did. I'm approving but want to make sure Scott is 👍🏻 also!

@MichaelParadis MichaelParadis merged commit 278eec4 into master Mar 12, 2026
14 of 15 checks passed
@MichaelParadis MichaelParadis deleted the MIKE/migrate-to-tanstack-router branch March 12, 2026 19:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants