---
# System prepended metadata

title: Routing & Folder Structure (Frontend)

---

# Routing & Folder Structure (Frontend)

## Routing structure

Here we will go through some important platform routes, and best-practices for creating new routes

### Important routes

#### Platform home route: 
These routes and its sub-routes are consumed by Teachers and students.
> https://staging-web.toddleapp.com/platform/IB_PYP/courses
> https://staging-web.toddleapp.com/platform/IB_MYP/courses

#### Admin route:
This route is consumed mostly by School admin for school setup, report generation, attendance management etc.
> https://staging-web.toddleapp.com/platform/administrator

#### Tools route:
This route and it's sub routes is accessed mainly by our toddle's school success team.
> https://staging-web.toddleapp.com/platform/tools

---

### Structure
Concieved on the basis on CRUD screens required for most modules
  |Route| Purpose |
|---|---|
|`/todos`|`show all todos`|
|`/todos/new`|`New todo creation page`|
|`/todos/id`|`shows only single todo`|
|`/todos/id/edit`|`single todo edit page`|

  - Webpack chunks are created at root feature level
  - Use kebab case for routes
  
>   In below example focus on family-conversations word

:-1: Not recommended
  ```
  1. /platform/IB_PYP/courses/4319/familyconversations/82
  2. /platform/IB_PYP/courses/4319/familyConversations/82
  3. /platform/IB_PYP/courses/4319/family_conversations/82
  4. /platform/IB_PYP/courses/4319/FAMILY-CONVERSATIONS/82
  ```
:+1: Recommended
  ```
   1. /platform/IB_PYP/courses/4319/family-conversations/82
  ```
  

---

## Folder Structure

```
├── components                  
├── commonComponents         # common components at module level
├── modules                 
│   └── ModuleFile           # this is where you keep action creators, action types & reducer.
│   └── QueryFile            # this is where you keep graphql       
|                            # queries related to a particular feature module
│   └── MutationFile         # this is where you keep graphql       
|                            # mutations related to a particular feature module
│   └── fragments            # this is where you keep graphql fragments
│   └── GraphQLHelperFile    # all the helper functions like
|                            # writing to cache or reading from apollo cache etc, are kept here.
│   └── commonMapStateToProps
├── routes                   # this folder contains the child routes of this feature and
|                            # follows the same folder structure above
├── index.js                 # this is where you initialize this feature route
|                            # and define path, inject reducer (or context)
```

For example: 
Lets say we want to create folder structure for /todo route

```
📦Todos
 ┣ 📂components
 ┃ ┣ 📂TodoBody
 ┃ ┃ ┣ 📜TodoBody.js
 ┃ ┃ ┣ 📜TodoBody.scss
 ┃ ┃ ┗ 📜index.js
 ┃ ┣ 📂TodoItemCard
 ┃ ┃ ┣ 📜TodoItemCard.js
 ┃ ┃ ┣ 📜TodoItemCard.scss
 ┃ ┃ ┗ 📜index.js
 ┃ ┣ 📂TodoItemList
 ┃ ┃ ┣ 📜TodoItemList.js
 ┃ ┃ ┣ 📜TodoItemList.scss
 ┃ ┃ ┗ 📜index.js
 ┃ ┣ 📂TopHeader
 ┃ ┃ ┣ 📜TopHeader.js
 ┃ ┃ ┣ 📜TopHeader.scss
 ┃ ┃ ┗ 📜index.js
 ┃ ┣ 📜Todos.js
 ┃ ┣ 📜Todos.scss
 ┃ ┗ 📜index.js
 ┣ 📂modules
 ┃ ┣ 📜TodosFragments.js
 ┃ ┣ 📜TodosGraphqlHelpers.js
 ┃ ┣ 📜TodosModule.js
 ┃ ┣ 📜TodosMutations.js
 ┃ ┗ 📜TodosQuery.js
 ┣ 📂routes
 ┗ 📜index.js
```
---
## Lazy Loading and defining a route

Define route in the `index.js` file, which is at the root of feature folder.
Always use lazy loading to asynchronously load the js files (or components) as we visit the route.

>Lazy loading is the technique of rendering only-needed or critical user interface items first, then quietly unrolling the non-critical items later.

For lazy loading, we use a custom HOC called `withAsyncRouteLoading` that internally uses [`require.ensure`](https://webpack.js.org/api/module-methods/#requireensure).

Let's take a look at an example below:

```
export default store => ({
  path: "platform",
  component: withAsyncRouteLoading(
    () =>
      new Promise((cb, reject) => {
        require.ensure(
          [],
          require => {
            const component = require("./components").default;
            const reducer = require("Platform/modules/PlatformModule").default;
            /*
            * injectReducer takes the reducer and combine it in
            * the redux global state, pretty much what combineReducer does.
            * This happens when we visit this route.
            */
            injectReducer(store, { key: "platform", reducer });
            /*
            * here this component will be rendered when we visit this route
            */
            cb(component);
          },
          err => {
            reject(err);
          },
          /*
          * this is the chunk name that webpack uses to generate bundles
          */
          "teacher-course"
        );
      })
  ),
  /*
  * these are all the child route, and follow pretty much the same process
  */
  childRoutes: [
    AdministratorRoute(store),
    ToolingRoute(store),
    TeacherRoute(store)
  ]
});
```