From edf2c1ec0ebc676efabe0f5e5b1fae4ca5649242 Mon Sep 17 00:00:00 2001 From: Nicholas Cunningham Date: Tue, 18 Mar 2025 13:47:42 -0600 Subject: [PATCH] docs(react): add React Router with Nx documentation to surface the support for React Router (#30384) This PR introduces a guide for using React Router with Nx and updates the Remix guide to reflect the transition to React Router. --- docs/generated/manifests/menus.json | 24 ++++ docs/generated/manifests/nx.json | 33 ++++++ docs/map.json | 5 + docs/shared/guides/react-router.md | 176 ++++++++++++++++++++++++++++ docs/shared/guides/remix.md | 6 + docs/shared/reference/sitemap.md | 1 + 6 files changed, 245 insertions(+) create mode 100644 docs/shared/guides/react-router.md diff --git a/docs/generated/manifests/menus.json b/docs/generated/manifests/menus.json index d76e3d16ff..2d19cc0314 100644 --- a/docs/generated/manifests/menus.json +++ b/docs/generated/manifests/menus.json @@ -1455,6 +1455,14 @@ "children": [], "disableCollapsible": false }, + { + "name": "React Router with Nx", + "path": "/recipes/react/react-router", + "id": "react-router", + "isExternal": false, + "children": [], + "disableCollapsible": false + }, { "name": "Use Environment Variables in React", "path": "/recipes/react/use-environment-variables-in-react", @@ -2837,6 +2845,14 @@ "children": [], "disableCollapsible": false }, + { + "name": "React Router with Nx", + "path": "/recipes/react/react-router", + "id": "react-router", + "isExternal": false, + "children": [], + "disableCollapsible": false + }, { "name": "Use Environment Variables in React", "path": "/recipes/react/use-environment-variables-in-react", @@ -2904,6 +2920,14 @@ "children": [], "disableCollapsible": false }, + { + "name": "React Router with Nx", + "path": "/recipes/react/react-router", + "id": "react-router", + "isExternal": false, + "children": [], + "disableCollapsible": false + }, { "name": "Use Environment Variables in React", "path": "/recipes/react/use-environment-variables-in-react", diff --git a/docs/generated/manifests/nx.json b/docs/generated/manifests/nx.json index f6401c1a7c..190f9d2536 100644 --- a/docs/generated/manifests/nx.json +++ b/docs/generated/manifests/nx.json @@ -1993,6 +1993,17 @@ "path": "/recipes/react/remix", "tags": [] }, + { + "id": "react-router", + "name": "React Router with Nx", + "description": "", + "mediaImage": "", + "file": "shared/guides/react-router", + "itemList": [], + "isExternal": false, + "path": "/recipes/react/react-router", + "tags": [] + }, { "id": "use-environment-variables-in-react", "name": "Use Environment Variables in React", @@ -3887,6 +3898,17 @@ "path": "/recipes/react/remix", "tags": [] }, + { + "id": "react-router", + "name": "React Router with Nx", + "description": "", + "mediaImage": "", + "file": "shared/guides/react-router", + "itemList": [], + "isExternal": false, + "path": "/recipes/react/react-router", + "tags": [] + }, { "id": "use-environment-variables-in-react", "name": "Use Environment Variables in React", @@ -3980,6 +4002,17 @@ "path": "/recipes/react/remix", "tags": [] }, + "/recipes/react/react-router": { + "id": "react-router", + "name": "React Router with Nx", + "description": "", + "mediaImage": "", + "file": "shared/guides/react-router", + "itemList": [], + "isExternal": false, + "path": "/recipes/react/react-router", + "tags": [] + }, "/recipes/react/use-environment-variables-in-react": { "id": "use-environment-variables-in-react", "name": "Use Environment Variables in React", diff --git a/docs/map.json b/docs/map.json index 9d8aec6a2f..28e55deb6a 100644 --- a/docs/map.json +++ b/docs/map.json @@ -659,6 +659,11 @@ "id": "remix", "file": "shared/guides/remix" }, + { + "name": "React Router with Nx", + "id": "react-router", + "file": "shared/guides/react-router" + }, { "name": "Use Environment Variables in React", "id": "use-environment-variables-in-react", diff --git a/docs/shared/guides/react-router.md b/docs/shared/guides/react-router.md new file mode 100644 index 0000000000..efdf8b6e75 --- /dev/null +++ b/docs/shared/guides/react-router.md @@ -0,0 +1,176 @@ +--- +title: React Router with Nx +description: Learn how to create, build, serve, and test React Router applications within an Nx workspace, leveraging Nx's powerful tooling for modern web development. +--- + +## React Router with Nx + +React Router is the successor of Remix and is the recommended routing library for new projects that may require Server-Side Routing (SSR). + +There are three modes when using React Router: `framework`, `declarative` and `data`. `Framework` mode is the most comprehensive and is what will be covered in this recipe. + +We'll show you how to create a [React Router](https://reactrouter.com/home) application with Nx. + +## Create Nx Workspace + +```{% command="npx create-nx-workspace@latest acme --preset=apps" path="~/" %} + +✔ Which stack do you want to use? · react +✔ What framework would you like to use? · none +✔ Application name · acme +✔ Would you like to use React Router for server-side rendering [https://reactrouter.com/]? · Yes +``` + +## Have an existing App? + +If you already have an existing React Router application and want to add Nx to it you can do so by running the following command: + +```shell +npx nx init +``` + +## Generate a React Router Application + +If you would like to generate a new React Router application, you can do so by running the following command in your Nx workspace + +```{% command="nx g @nx/react:app apps/happynrwl --routing --use-react-router" path="~/acme" %} + +``` + +There is no need to install any additional plugins to use React Router with Nx. The `@nx/react` plugin already includes support for React Router. + +## Running the Application + +Now that you have created your React Router application with Nx you can build, serve and test with the following commands: + +### Build + +To build your application run the following command: + +```{% command="nx build happynrwl" path="~/acme" %} + +> nx run acme:happynrwl + +> react-router build + +vite v6.2.1 building for production... +✓ 45 modules transformed. +build/client/.vite/manifest.json 1.40 kB │ gzip: 0.32 kB +build/client/assets/about-D7ArdXr1.js 0.20 kB │ gzip: 0.18 kB +build/client/assets/with-props-CQyfqcsx.js 0.22 kB │ gzip: 0.19 kB +build/client/assets/root-BKqDrCrU.js 0.99 kB │ gzip: 0.54 kB +build/client/assets/app-DnLbn-a2.js 24.50 kB │ gzip: 6.26 kB +build/client/assets/chunk-K6CSEXPM-DXuCqE6i.js 111.05 kB │ gzip: 37.47 kB +build/client/assets/entry.client-CkXnIIWp.js 179.95 kB │ gzip: 56.93 kB +✓ built in 576ms +vite v6.2.1 building SSR bundle for production... +✓ 9 modules transformed. +build/server/.vite/manifest.json 0.17 kB +build/server/index.js 43.12 kB +✓ built in 35ms + + + + NX Successfully ran target build for project happynrwl (1s) +``` + +### Serve (Development) + +To serve your application for development use the following command: + +```{% command="nx dev happynrwl" path="~/acme" %} +> nx run happynrwl:dev + +> react-router dev + +1:30:42 p.m. [vite] (client) Re-optimizing dependencies because lockfile has changed + ➜ Local: http://localhost:4200/ + ➜ press h + enter to show help +``` + +### Serve (Production) + +To serve your application's production build use the following command: + +```{% command="nx start happynrwl" path="~/acme" %} +> nx run happynrwl:build + +> react-router build + +vite v6.2.1 building for production... +✓ 45 modules transformed. +build/client/.vite/manifest.json 1.40 kB │ gzip: 0.32 kB +build/client/assets/about-D7ArdXr1.js 0.20 kB │ gzip: 0.18 kB +build/client/assets/with-props-CQyfqcsx.js 0.22 kB │ gzip: 0.19 kB +build/client/assets/root-BKqDrCrU.js 0.99 kB │ gzip: 0.54 kB +build/client/assets/app-DnLbn-a2.js 24.50 kB │ gzip: 6.26 kB +build/client/assets/chunk-K6CSEXPM-DXuCqE6i.js 111.05 kB │ gzip: 37.47 kB +build/client/assets/entry.client-CkXnIIWp.js 179.95 kB │ gzip: 56.93 kB +✓ built in 576ms +vite v6.2.1 building SSR bundle for production... +✓ 9 modules transformed. +build/server/.vite/manifest.json 0.17 kB +build/server/index.js 43.12 kB +✓ built in 35ms + +> nx run happynrwl:start + +> react-router-serve build/server/index.js + +[react-router-serve] http://localhost:3000 (http://192.168.0.112:3000) +``` + +{% callout type="note" title="PORT" %} +The default port for `production` is 3000 if you want to change it use the PORT environment variable +{% /callout %} + +### Unit Test + +To unit test the application run the following command: + +```{% command="nx test happynrwl" path="~/acme" %} +> nx run happynrwl:test + +> vitest + + + RUN v3.0.8 /private/tmp/projects/acme/apps/happynrwl + + ✓ tests/routes/_index.spec.tsx (1 test) 45ms + ✓ renders loader data + + Test Files 1 passed (1) + Tests 1 passed (1) + Start at 13:40:29 + Duration 807ms (transform 59ms, setup 0ms, collect 168ms, tests 45ms, environment 372ms, prepare 52ms) +``` + +## Generate a Route + +By default a route is generated for you when you create a new React Router application. If you would like to generate a new route you can do so by running the following command: + +```{% command="nx g @nx/react:component --path=apps/happynrwl/app/routes/contact" path="~/happynrwl" %} +CREATE apps/happynrwl/app/routes/contact.tsx +CREATE apps/happynrwl/app/routes/contact.module.scss +CREATE apps/happynrwl/app/routes/contact.spec.tsx +``` + +Now we have create a new route called `contact` in our application. Let's add that route to our `routes.tsx` file. + +```tsx +import { type RouteConfig, index, route } from "@react-router/dev/routes"; + +export default [ + index('./app.tsx'), + route('about', './routes/about.tsx') + route('contact', './routes/contact.tsx') + ] satisfies RouteConfig; +``` + +Now if we serve or app and navigate to `https://localhost:4200/contact` we will see our new route. + +## GitHub Repository with Example + +You can find an example of an Nx Workspace using React Router by clicking below + +{% github-repository url="" /%} diff --git a/docs/shared/guides/remix.md b/docs/shared/guides/remix.md index 214c0ae321..d3f783e422 100644 --- a/docs/shared/guides/remix.md +++ b/docs/shared/guides/remix.md @@ -3,6 +3,12 @@ title: Remix with Nx description: Learn how to create, build, serve, and test Remix applications within an Nx workspace, leveraging Nx's powerful tooling for modern web development. --- +{% callout type="warning" title="The future of Remix is React Router" %} +Remix has announced its transition to React Router. The `@nx/remix` plugin is based on Remix v2 and is incompatible with the latest version of React Router unless you [upgrade](https://reactrouter.com/upgrading/remix) your Remix application. In the future, the `@nx/remix` plugin will be deprecated in favor of the `@nx/react/router` plugin. If you are starting a new project, we recommend using the `@nx/react/router` plugin instead. + +For an example of how to use React Router with Nx, see the [React Router with Nx](/recipes/react/react-router) recipe. +{% /callout %} + # Remix with Nx In this recipe, we'll show you how to create a [Remix](https://remix.run) application with Nx. diff --git a/docs/shared/reference/sitemap.md b/docs/shared/reference/sitemap.md index 8e92061260..fbcbf9470d 100644 --- a/docs/shared/reference/sitemap.md +++ b/docs/shared/reference/sitemap.md @@ -101,6 +101,7 @@ - [React](/recipes/react) - [React Native with Nx](/recipes/react/react-native) - [Remix with Nx](/recipes/react/remix) + - [React Router with Nx](/recipes/react/react-router) - [Use Environment Variables in React](/recipes/react/use-environment-variables-in-react) - [Using Tailwind CSS in React](/recipes/react/using-tailwind-css-in-react) - [Adding Images, Fonts, and Files](/recipes/react/adding-assets-react)