# Creating a Simple Single Page Web App (SPA)

### TL;DR - from the command line, run:

```bash
mkdir myapp
cd myapp

npx reactium init

[ARCLI] > Initialize what type of project?:  (Use arrow keys)
❯ Reactium (Web Application) 
  Actinium (Web API) 

# Delete the default component
rm -rf src/app/components/Welcome

# Create Your Home Page!
npx reactium component

[ARCLI] > Select directory:  src/app/components
❯ src/app/components
  src/app/components/common-ui
  
[ARCLI] > Component Name:  Home

[ARCLI] > Route:  /

[ARCLI] > Reactium Hooks?:  Yes

[ARCLI] > Domain file?:  Yes

[ARCLI] > Stylesheet?:  Yes

[ARCLI] > Select stylesheet type:  
  base 
  atoms 
  molecules 
❯ organisms 
  overrides 
  default 
  mixins
  
[ARCLI] > Preflight checklist:
{
  "destination": "src/app/components/Home",
  "name": "Home",
  "route": "['/']",
  "hooks": true,
  "domain": true,
  "style": true,
  "styleType": "_reactium-style-organisms.scss",
  "className": "home",
  "index": true
}

[ARCLI] > Proceed?:  (y/N) y

npm run local  
```

That's it. You should be looking at a running simple app, with your **`Home`** component running on <http://localhost:3000>

### Creating A Page

Let's break down what's happening with the previous `reactium` command. After proceeding, your `scr/app` directory should look something like this:

```
src/app
├── components
│   ├── Home
│   │   ├── Home.jsx
│   │   ├── reactium-domain-home.js <- defines the unique namespace of our component
│   │   ├── reactium-hooks-home.js <- Reactium plugin hooks go here
│   │   ├── reactium-route-home.js <- Defines the Route where this component renders in the front-end
│   │   └── _reactium-style-organisms-Home.scss <- Styles go here
└── main.js <- The main entry point of the app (usually no modifications needed)
```

### Create a Second Page

```bash
npx reactium component

[ARCLI] > Select directory:  src/app/components
❯ src/app/components
  src/app/components/common-ui
  
[ARCLI] > Component Name:  About

[ARCLI] > Route:  /about

[ARCLI] > Reactium Hooks?:  Yes

[ARCLI] > Domain file?:  Yes

[ARCLI] > Stylesheet?:  Yes

[ARCLI] > Select stylesheet type:  
  base 
  atoms 
  molecules 
❯ organisms 
  overrides 
  default 
  mixins
  
[ARCLI] > Preflight checklist:
{
  "destination": "src/app/components/About",
  "name": "About",
  "route": "['/about']",
  "hooks": true,
  "domain": true,
  "style": true,
  "styleType": "_reactium-style-organisms.scss",
  "className": "about",
  "index": true
}

[ARCLI] > Proceed?:  (y/N) y
```

### Single Page Application Navigation

You already have a React single-page application started.&#x20;

Let's create a navigation component and render it on both pages!

```bash
npx reactium component

[ARCLI] > Select directory:  common-ui
❯ src/app/components/common-ui

[ARCLI] > Component Name:  Nav

[ARCLI] > Route:
[ARCLI] > Reactium Hooks?:  (Y/n)  Yes
[ARCLI] > Domain file?:  (Y/n)  Yes

[ARCLI] > Stylesheet?:  (Y/n) Yes
  variables 
  base 
  atoms 
❯ molecules 
  organisms 
  overrides 
  default 
(Move up and down to reveal more choices)

[ARCLI] > Preflight checklist:

{
  "destination": "src/app/components/common-ui/Nav",
  "name": "Nav",
  "route": "[]",
  "hooks": true,
  "domain": true,
  "style": true,
  "styleType": "_reactium-style-molecules",
  "className": "nav",
  "index": true
}

[ARCLI] > Proceed?:  (Y/n) Yes
```

Ok, let's modify our Nav component:

{% code title="common-ui/Nav/Nav.jsx" %}

```jsx
import React from 'react';
import { NavLink } from 'react-router-dom';

/**
 * -----------------------------------------------------------------------------
 * Component: Nav
 * -----------------------------------------------------------------------------
 */
export const Nav = ({ className }) => {
    return (
        <nav className={className}>
            <NavLink to='/' exact={true} activeClassName='active'>
                Home
            </NavLink>
            <NavLink to='/about' activeClassName='active'>
                About
            </NavLink>
        </nav>
    );
};

Nav.defaultProps = {
    className: 'nav',
};

export default Nav;
```

{% endcode %}

Let's also add some sassy styles for Nav:

{% code title="common-ui/Nav/\_reactium-style-molecules-Nav.scss" %}

```scss
.nav {
    display: flex;
    flex-direction: column;
    padding: 20px;

    a {
      &, &:visited {
        color: gray;
      }
      &:hover, &.active {
        color: black;
      }
    }
}
```

{% endcode %}

Great, now let's include the Nav in both the Home page and the About page:

{% tabs %}
{% tab title="Home.jsx" %}

```jsx
import {
    useSyncState,
    useHookComponent,
} from '@atomic-reactor/reactium-core/sdk';
import React from 'react';

/**
 * -----------------------------------------------------------------------------
 * Component: Home
 * -----------------------------------------------------------------------------
 */
export const Home = ({ className }) => {
    const Nav = useHookComponent('Nav');
    const state = useSyncState({ content: 'Home' });

    return (
        <div className={className}>
            <Nav />
            <h1>{state.get('content')}</h1>
            <p>This is the Home page.</p>
        </div>
    );
};

Home.defaultProps = {
    className: 'home',
};

export default Home;
```

<figure><img src="https://2573846121-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M4poMvugQiWii-2eM1T%2Fuploads%2F9Iv9g0kZWXiXDuoxsTqj%2Fimage.png?alt=media&#x26;token=d7071660-d68b-4079-9696-f395aab34d4a" alt=""><figcaption><p>/</p></figcaption></figure>
{% endtab %}

{% tab title="About.jsx" %}

```jsx
import {
    useSyncState,
    useHookComponent,
} from '@atomic-reactor/reactium-core/sdk';
import React from 'react';

/**
 * -----------------------------------------------------------------------------
 * Component: About
 * -----------------------------------------------------------------------------
 */
export const About = ({ className }) => {
    const Nav = useHookComponent('Nav');
    const state = useSyncState({ content: 'About' });

    return (
        <div className={className}>
            <Nav />
            <h1>{state.get('content')}</h1>
            <p>This is the About page.</p>
        </div>
    );
};

About.defaultProps = {
    className: 'about',
};

export default About;
```

<figure><img src="https://2573846121-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M4poMvugQiWii-2eM1T%2Fuploads%2FOmCLY8cQh4n5bxUddqqy%2Fimage.png?alt=media&#x26;token=846911b0-c835-45d9-9923-0bf62844ad6a" alt=""><figcaption><p>/about</p></figcaption></figure>
{% endtab %}
{% endtabs %}

### Great, Now we are SPA Routing!

But wait, does that mean I have to have common elements like the **`Nav`** on every routed page?

Let's create an **`AppParent`** component to be the "window dressing" for our app!

```bash
npx reactium component

[ARCLI] > Select directory:  common-ui
❯ src/app/components/common-ui

[ARCLI] > Component Name:  AppParent

[ARCLI] > Route:
[ARCLI] > Reactium Hooks?:  (Y/n)  Yes
[ARCLI] > Domain file?:  (Y/n)  Yes

[ARCLI] > Stylesheet?:  (Y/n) Yes
  variables 
  base 
  atoms 
  molecules 
❯ organisms 
  overrides 
  default 
(Move up and down to reveal more choices)

[ARCLI] > Preflight checklist:

{
  "destination": "src/app/components/common-ui/AppParent",
  "name": "AppParent",
  "route": "[]",
  "hooks": true,
  "domain": true,
  "style": true,
  "styleType": "_reactium-style-organisms",
  "className": "appparent",
  "index": true
}

[ARCLI] > Proceed?:  (Y/n) Yes
```

Let's move the **`Nav`** to the **`AppParent`** component, and add some common page structure to the app.

{% tabs %}
{% tab title="AppParent.jsx" %}

```jsx
import { useHookComponent } from '@atomic-reactor/reactium-core/sdk';
import React from 'react';

/**
 * -----------------------------------------------------------------------------
 * Component: AppParent
 * -----------------------------------------------------------------------------
 */
export const AppParent = ({ className, children }) => {
    const Nav = useHookComponent('Nav');
    const Footer = useHookComponent('Footer');
    return (
        <main className={className}>
            <aside className='main-nav'>
                <Nav />
            </aside>
            <section className='main-content'>{children}</section>
            <footer className='main-footer'>
                <Footer />
            </footer>
        </main>
    );
};

AppParent.defaultProps = {
    className: 'appparent main',
};

export default AppParent;

```

{% hint style="success" %}
Note that the **`Footer`** component need not actually already exist. If someone creates one with that name, it will just show up!
{% endhint %}

{% hint style="success" %}
By creating an **`AppParent`** component that returns **`props.children`**, it will automatically take the place of the component in reactium-core. Registered components are overridden! A good thing!
{% endhint %}
{% endtab %}

{% tab title="\_reactium-style-organisms-AppParent.scss" %}

```scss
.main {
    padding: 50px;
    &-nav, &-content {
      border-bottom: 1px solid black;
    }

    &-content {
      padding: 20px 0;
    }
}

```

{% endtab %}

{% tab title="Home.jsx" %}

```jsx
import { useSyncState } from '@atomic-reactor/reactium-core/sdk';
import React from 'react';

/**
 * -----------------------------------------------------------------------------
 * Component: Home
 * -----------------------------------------------------------------------------
 */
export const Home = ({ className }) => {
    const state = useSyncState({ content: 'Home' });

    return (
        <div className={className}>
            <h1>{state.get('content')}</h1>
            <p>This is the Home page.</p>
        </div>
    );
};

Home.defaultProps = {
    className: 'home',
};

export default Home;

```

{% endtab %}

{% tab title="About.jsx" %}

```jsx
import { useSyncState } from '@atomic-reactor/reactium-core/sdk';
import React from 'react';

/**
 * -----------------------------------------------------------------------------
 * Component: About
 * -----------------------------------------------------------------------------
 */
export const About = ({ className }) => {
    const state = useSyncState({ content: 'About' });

    return (
        <div className={className}>
            <h1>{state.get('content')}</h1>
            <p>This is the About page.</p>
        </div>
    );
};

About.defaultProps = {
    className: 'about',
};

export default About;
```

{% endtab %}

{% tab title="\_reactium-style-molecules-Nav.scss" %}

```scss
.nav {
    display: flex;

    a {
        padding: 10px 20px;
        &,
        &:visited,
        &:hover,
        &:active {
            text-decoration: none;
        }

        &,
        &:visited {
            color: gray;
        }
        &:hover,
        &.active {
            color: white;
            background: gray;
        }
    }
}

```

{% endtab %}
{% endtabs %}

### Final Simple SPA

<figure><img src="https://2573846121-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M4poMvugQiWii-2eM1T%2Fuploads%2Ft8Nitl6VBvDu8yxTguRh%2Fimage.png?alt=media&#x26;token=a7ebbc03-8bef-46ef-9faa-163348e35d61" alt=""><figcaption><p>Front-end Routed Single Page Application</p></figcaption></figure>
