10.3 Reference - React-router Project Templates
Tags: beginners, javascript, react, router
Published: 2023-03-13 16:14:04

Last Reviewed: September 2023 

### Introduction ###

If you use `React` in your webapps, it's quite likely that you will end up using `React-router` as well. This is because even the simplest single-page `https://mywebsite.com` webapp will likely find it useful to register an https://`mywebsite.com/management` secured page in order to maintain its configuration data. 

So, if all your `React` projects are going to be based on `React-router` designs, it seems that it would be a good idea if they share common folder structure and file-naming conventions specifically suited to a `React-router` single-page webapp.

Here's what I've been using for both folder structure and file-naming (acknowledgments here go to [Faraz Ahmad](https://betterprogramming.pub/an-opinionated-guide-to-react-folder-structure-file-naming-8b723d39a0d6)), together with a sample code template for a popular `react-router` use-case

### Folder structure and File-naming conventions###

A structure I've been using successfully for a while on my Vite React Router projects now goes like this:

![Folder structure](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ylcw01mjmjj8ysca74r0.jpg)

* `assets` - graphic files etc
* `components` - components that are shared around the webapp
* `lib` - javascript functions and constants that are likewise shared around the webapp
* `routes` - "master" components defining the webapps routes. Sub-components local to a master component are declared within that component
* `styles` - shared stylesheets

Hosting your fixed `assets` in the public folder as shown above makes for simplicity but means that they aren't built into the webapp's "bundle". This suits me but your case may be different. See [Where to Store Images in React App](https://www.upbeatcode.com/react/where-to-store-images-in-react-app/#:~:text=Most%20react%20developers%20tend%20to,images%20in%20src%2Fassets%20folder) for a useful discussion of this issue.

Because component functions are commonly signaled by capitalisation of the first character of their name, I've found it best to follow the same convention for naming source file names as well. Where sub-components are only referenced by their parent, I find it reduces clutter if I put their code within their parent's file. 

Note that, if you plan to use Vite as your local development server, component files containing JSX are expected to use .jsx filename extensions.

If you have a deep interest in project structures, you might find it useful to have a look at [Configuring a Firebase/React webapp for life post-implementation](https://dev.to/mjoycemilburn/taming-the-firebase-emulator-configuring-a-firebasereact-webapp-for-life-post-implementation-193i). This describes the problems you may encounter when trying to test enhancements to a system that is already in operational use. The solution proposed here works well for me and may help you too.



###Code template for a "persistent tabs" webapp###
A layout you'll see time and time again in website layouts is one that uses some sort of persistent "menu" to control the "page" content that populates the rest of the available screen space.

Typically this arrangement will take the form of a menu bar with clickable "tabs". These determine the page displayed beneath the bar.

React-router is great for delivering this sort of design. Here's code for a Vite `main.jsx` file delivering a persistent `Tabs.jsx` menu component controlling `RouteA.jsx` and `RouteB.jsx` page components. The persistence of the Tabs component is achieved by adding a React `<Outlet />` tag to the Tabs component

Note an interesting feature of the sample code. Generally, one of your route pages will be designated a Home page - ie the page that is displayed by default when the webappp starts. In order to get this page rendered both when the webapp is called with the root url as well as when the page is called with its own root/.. url, the trick is to make this page an `index` Route. This means that it gets rendered when none of the other Routes match the url.

Here's my `main.jsx` template. In this case, the RouteA component has been selected to be the "indexed" Home page:
```jsx
import React from "react";
import ReactDOM from "react-dom/client";
import { createBrowserRouter, createRoutesFromElements, RouterProvider, } from "react-router-dom";
import { Route } from "react-router-dom";

import { Tabs } from './routes/Tabs';
import { RouteA } from './routes/RouteA';
import { RouteB } from './routes/RouteB';

const router = createBrowserRouter(
    createRoutesFromElements(
            <Route path="" element={<Tabs />} >
                <Route path="/routea" element={<RouteA />} />
                <Route path="/routeb" element={<RouteB />} />

                <Route index element={<RouteA />} />

            </Route>
    )
)

ReactDOM.createRoot(document.getElementById("root")).render(
    <React.StrictMode>
        <RouterProvider router={router} />
    </React.StrictMode>
);


```
Here's the `Tabs.js` component that delivers the "menu" bar. This lays out a header menu bar that uses `React-router`'s  basic `Link` component to activate a route change. You can add an `onClick` function to the component tag's invocation if you want to do something fancy like setting state when the tab is clicked. You might also consider replacing `<Link>` by `<NavLink>` if you'd like the tab's formatting to reflect its "clicked" state.

```javascript
import { Link, Outlet } from "react-router-dom";

function Tabs() {

    return (
        <div>
            <Link to="/routea">RouteA</Link>&nbsp;&nbsp;<Link to="/routeb">RouteB</Link>
            <Outlet />
        </div>
    );
}
export { Tabs }
```

And finally, here's my `RouteA.js`. This displays content for page A beneath the persistent Tabs menu bar. Further pages, obviously, will be just clones of this.

```javascript
function RouteA() {
    return (<h2>RouteA output</h2>);
}

export { RouteA }
```
### Practical issues ###

1. While the example shown above uses JSX to configure the webapp's routes in `src/main.jsx`, this specification could just as easily have been suppled as a javascript object. Personally I find JSX more natural.

2. It seems (as of March 2023) that "out of the box", Vite's scaffolding of your project won't configure a linter. This means you won't know about code issues until they actually cause a problem. For instructions on how to fix this (at the expense of some reduction in the speed advantages of Vite over React), see [Vite with ESLint](https://www.robinwieruch.de/vite-eslint/)

3. Likewise, once you've configured firebase, `firebase.json` hosting will initially be pointing to `"public" : "public"`. After you've built a React Router project with `npm run build`, you'll need to change this to `"public": "dist"`, before deploying.

4. To enable debugging in the browser for webapps built using Vite, configure the `vite.config.js` file in a project's root as follows:
```javascript
export default defineConfig({
    plugins: [react()],
    build: {sourcemap: true,},
})
```

5. Complete the setup by adding your project folder to the Inspector's workspace.You'll find your source under the new entry that will appear here once you've approved use.

6. In order to obtain Google indexing for "logical pages" defined by your tabs you'll need to create `<head>` information within their `return()` code. See [Highs and Lows of a Firebase/React Development](https://dev.to/mjoycemilburn/highs-and-lows-of-a-firebasereact-development-2olh) for advice on this. Also note that, by default, the indexing of your root page will be guided by the `<head>` settings in your `index.html` file.