From e8ab9ead4a4c70d75205804536e3adc47aea2a15 Mon Sep 17 00:00:00 2001 From: SeanCassiere <33615041+SeanCassiere@users.noreply.github.com> Date: Sat, 20 Apr 2024 17:02:52 +1200 Subject: [PATCH 1/4] docs: add migration guide for react-location --- .../react/migrate-from-react-location.md | 272 ++++++++++++++++++ 1 file changed, 272 insertions(+) create mode 100644 docs/framework/react/migrate-from-react-location.md diff --git a/docs/framework/react/migrate-from-react-location.md b/docs/framework/react/migrate-from-react-location.md new file mode 100644 index 00000000000..622fcf311bb --- /dev/null +++ b/docs/framework/react/migrate-from-react-location.md @@ -0,0 +1,272 @@ +--- +title: Migration from React Location +--- + +Before you begin your journey in migrating from React Location, its important that you have a good understanding of the [Routing Concepts](../guide/routing-concepts) and [Design Decisions](../decisions-on-dx) used by TanStack Router. + +## Differences between React Location and TanStack Router + +React Location and TanStack Router share much of same design decisions concepts, but there are some key differences that you should be aware of. + +- React Location uses _generics_ to infer types for routes, while TanStack Router uses _module declaration merging_ to infer types. +- Route configuration in React Location is done using a single array of route definitions, while in TanStack Router, route configuration is done using a tree of route definitions starting with the [root route](../guide/routing-concepts#the-root-route). +- [File-based routing](../guide/file-based-routing) is the recommended way to define routes in TanStack Router, while React Location only allows you to define routes in a single file using a code-based approach. + - TanStack Router does support a [code-based approach](../guide/code-based-routing) to defining routes, but it is not recommended for most use cases. You can read more about why, over here: [why is file-based routing the preferred way to define routes?](../decisions-on-dx#3-why-is-file-based-routing-the-preferred-way-to-define-routes) + +## Migration guide + +In this guide we'll go over the process of migrating the [React Location Basic example](https://github.com/TanStack/router/tree/react-location/examples/basic) over to TanStack Router using file-based routing, with the end goal of having the same functionality as the original example (styling and other non-routing related code will be omitted). + +> **Note:** To use a code-based approach for defining your routes, you can read the [code-based Routing](../guide/code-based-routing) guide. + +### Step 1: Swap over to TanStack Router's dependencies + +First, we need to install the dependencies for TanStack Router. + +```bash +npm install @tanstack/react-router @tanstack/router-devtools +``` + +And remove the React Location dependencies. + +```bash +npm uninstall @tanstack/react-location @tanstack/react-location-devtools +``` + +### Step 2: Use the file-based routing watcher + +If your project uses vite, you can use the our plugin to watch for changes in your routes files and automatically update the routes configuration. + +Install the vite plugin: + +```bash +npm install -D @tanstack/router-vite-plugin +``` + +And add it to your `vite.config.js`: + +```js +import { defineConfig } from 'vite' +import react from '@vitejs/plugin-react' +import { TanStackRouterVite } from '@tanstack/router-vite-plugin' + +export default defineConfig({ + // ... + plugins: [TanStackRouterVite(), react()], +}) +``` + +However, if your application does not use vite, you can use the `@tanstack/router-cli` package to watch for changes in your routes files and automatically update the routes configuration. + +```bash +npm install -D @tanstack/router-cli +``` + +And add a script to your `package.json`: + +```json +{ + "scripts": { + "dev": "tsr watch" + } +} +``` + +### Step 3: Add the file-based configuration file to your project + +Create a `tsr.config.json` file in the root of your project with the following content: + +```json +{ + "routesDirectory": "./src/routes", + "generatedRouteTree": "./src/routeTree.gen.ts" +} +``` + +You can find the full list of options for the `tsr.config.json` file over [here](../guide/file-based-routing#options). + +### Step 4: Create the routes directory + +Create a `routes` directory in the `src` directory of your project. + +```bash +mkdir src/routes +``` + +### Step 5: Create the root route file + +```tsx +// src/routes/__root.tsx +import { createRootRoute, Outlet, Link } from '@tanstack/react-router' +import { TanStackRouterDevtools } from '@tanstack/router-devtools' + +export const Route = createRootRoute({ + component: () => { + return ( + <> +
+ + Home + + Posts +
+
+ + + + ) + }, +}) +``` + +### Step 6: Create the index route file + +```tsx +// src/routes/index.tsx +import { createFileRoute } from '@tanstack/react-router' + +export const Route = createFileRoute({ + component: Index, +}) +``` + +> You will need to move any related components and logic needed for the index route from the `src/index.tsx` file to the `src/routes/index.tsx` file. + +### Step 7: Create the posts route file + +```tsx +// src/routes/posts.tsx +import { createFileRoute, Link } from '@tanstack/react-router' + +export const Route = createFileRoute({ + component: Posts, + loader: async () => { + const posts = await fetchPosts() + return { + posts, + } + }, +}) + +function Posts() { + const { posts } = Route.useLoaderData() + return ( +
+ {posts.map((post) => ( + + {post.title} + + ))} +
+ ) +} +``` + +> You will need to move any related components and logic needed for the posts route from the `src/index.tsx` file to the `src/routes/posts.tsx` file. + +### Step 8: Create the posts index route file + +```tsx +// src/routes/posts.index.tsx +import { createFileRoute } from '@tanstack/react-router' + +export const Route = createFileRoute({ + component: PostsIndex, +}) +``` + +> You will need to move any related components and logic needed for the posts index route from the `src/index.tsx` file to the `src/routes/posts.index.tsx` file. + +### Step 9: Create the posts id route file + +```tsx +// src/routes/posts.$postId.tsx +import { createFileRoute } from '@tanstack/react-router' + +export const Route = createFileRoute({ + component: PostsId, + loader: async ({ params: { postId } }) => { + const post = await fetchPost(postId) + return { + post, + } + }, +}) + +function PostsId() { + const { post } = Route.useLoaderData() + // ... +} +``` + +> You will need to move any related components and logic needed for the posts id route from the `src/index.tsx` file to the `src/routes/posts.$postId.tsx` file. + +### Step 10: Generate the route tree + +If you are using vite as your bundler, the route tree will be generated automatically when you run the dev script. + +If you are not using vite, you can generate the route tree by running the following command: + +```bash +npx tsr generate +``` + +### Step 11: Update the main entry file to render the Router + +Once you've generated the route-tree, you can then update the `src/index.tsx` file to create the router instance and render it. + +```tsx +// src/index.tsx +import React from 'react' +import ReactDOM from 'react-dom' +import { createRouter, RouterProvider } from '@tanstack/react-router' + +// Import the generated route tree +import { routeTree } from './routeTree.gen' + +// Create a new router instance +const router = createRouter({ routeTree }) + +// Register the router instance for type safety +declare module '@tanstack/react-router' { + interface Register { + router: typeof router + } +} + +const domElementId = 'root' // Assuming you have a root element with the id 'root' + +// Render the app +const rootElement = document.getElementById(domElementId) +if (!rootElement) { + throw new Error(`Element with id ${domElementId} not found`) +} + +ReactDOM.createRoot(rootElement).render( + + + , +) +``` + +### Finished! + +You should now have successfully migrated your application from React Location to TanStack Router using file-based routing. + +React Location also has a few more features that you might be using in your application. Here are some guides to help you migrate those features: + +- [Search params](../guide/search-params) +- [Data loading](../guide/data-loading) +- [History types](../guide/history-types) +- [Wildcard / Splat / Catch-all routes](../guide/routing-concepts#splat--catch-all-routes) +- [Authenticated routes](../guide/authenticated-routes) + +TanStack Router also has a few more features that you might want to explore: + +- [Router Context](../guide/router-context) +- [Preloading](../guide/preloading) +- [Pathless / Layout Routes](../guide/routing-concepts#pathless--layout-routes) +- [Route masking](../guide/route-masking) +- ... and more! + +If you are facing any issues or have any questions, feel free to ask for help in the TanStack Discord. From 24a822c5ce910d637eab6eea8da37f76e245e399 Mon Sep 17 00:00:00 2001 From: SeanCassiere <33615041+SeanCassiere@users.noreply.github.com> Date: Sat, 20 Apr 2024 17:03:14 +1200 Subject: [PATCH 2/4] chore: show the react-location migration guide --- docs/config.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/config.json b/docs/config.json index 8e0207417b6..65f358bce88 100644 --- a/docs/config.json +++ b/docs/config.json @@ -37,6 +37,10 @@ "label": "Migrate from React Router", "to": "framework/react/migrate-from-react-router" }, + { + "label": "Migrate from React Location", + "to": "framework/react/migrate-from-react-location" + }, { "label": "Decisions on DX", "to": "framework/react/decisions-on-dx" From 92f18099cad0426d4ba95ed1e0963e4b9c4943c0 Mon Sep 17 00:00:00 2001 From: SeanCassiere <33615041+SeanCassiere@users.noreply.github.com> Date: Sat, 20 Apr 2024 17:07:50 +1200 Subject: [PATCH 3/4] docs: remove the word "over" --- docs/framework/react/migrate-from-react-location.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/framework/react/migrate-from-react-location.md b/docs/framework/react/migrate-from-react-location.md index 622fcf311bb..f49ff948376 100644 --- a/docs/framework/react/migrate-from-react-location.md +++ b/docs/framework/react/migrate-from-react-location.md @@ -83,7 +83,7 @@ Create a `tsr.config.json` file in the root of your project with the following c } ``` -You can find the full list of options for the `tsr.config.json` file over [here](../guide/file-based-routing#options). +You can find the full list of options for the `tsr.config.json` file [here](../guide/file-based-routing#options). ### Step 4: Create the routes directory From a40d6d29f240ca879cd8aef9e15119e93153bef0 Mon Sep 17 00:00:00 2001 From: SeanCassiere <33615041+SeanCassiere@users.noreply.github.com> Date: Sat, 20 Apr 2024 17:08:27 +1200 Subject: [PATCH 4/4] docs: make ssr a guide to feature --- docs/framework/react/migrate-from-react-location.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/framework/react/migrate-from-react-location.md b/docs/framework/react/migrate-from-react-location.md index f49ff948376..29b4b14e238 100644 --- a/docs/framework/react/migrate-from-react-location.md +++ b/docs/framework/react/migrate-from-react-location.md @@ -267,6 +267,7 @@ TanStack Router also has a few more features that you might want to explore: - [Preloading](../guide/preloading) - [Pathless / Layout Routes](../guide/routing-concepts#pathless--layout-routes) - [Route masking](../guide/route-masking) +- [SSR](../guide/ssr) - ... and more! If you are facing any issues or have any questions, feel free to ask for help in the TanStack Discord.