Exploring Factor - A Wordpress replacement 
 in Vue & Typescript
Tags: vue, typescript, factorcms
Published: 2020-02-14 17:00:40

Factor ([factor.dev](https://factor.dev)) is a modern Javascript CMS based on the VENM stack - Vue, Express, Node Mongo (a.k.a the MEVN stack).

Why seek a wordpress alternative? Wordpress has been the workhorse of a generation of web devs, but it is slow. Factor wraps Wordpress like functionality in Vue & renders extremely quickly.


In Part 1 of this tutorial we will set up a basic Factor site.

In Part 2 we will explore Factor from a Wordpress perspective - Posts, Pages & Custom Post Types.

## Part 1
* [Set up Factor](#chapter-1)
* [Create a Mongo DB](#chapter-2)
* [Create Admin User](#chapter-3)
* [Verify Admin User](#chapter-4)



## Set up Factor <a name="chapter-1"></a>

Ensure [node](https://nodejs.org/en/) and [npx](https://www.npmjs.com/package/npx) are installed:


Open a terminal in ***~/***

```
git clone https://github.com/happyrobotstudio/factor-tute-1.git

cd factor-tute-1

npm install

```

And let's build our Factor app:

```
npx factor dev
```


Open in a Browser:
```
http://localhost:3000/
```

And we should see our new Factor app, 

![localhost:3000](https://i.ibb.co/ydqqw3B/Factor2.png)
![localhost:3000/page](https://i.ibb.co/5FVSzfK/Factor3.png)



Our Factor app looks very much like a simple Vue app at this stage,


Factor handles our routing with **addContentRoute**


**index.js**
```javascript
import { addContentRoute } from "@factor/api"

addContentRoute({
  path: "/",
  component: () => import("./home.vue")
})

addContentRoute({
  path: "/page",
  component: () => import("./page.vue")
})
```


Our basic app layout, a header/footer and our main ``<router-view>``

**content.vue**
```vue
<template>
  <div class="content">

    <page-header></page-header>
    <router-view />
    <page-footer></page-footer>

  </div>
</template>

<script lang="ts">
  export default {
    components: {
      pageHeader: () => import("./header.vue"),
      pageFooter: () => import("./footer.vue")
    }
  }
</script>
```

A home page template,

**home.vue**
```vue
<template>
  <div class="page home-page">

    <h1>Excellent Home Page</h1>

  </div>
</template>

<script lang="ts">
  export default {
    components: {

    }
  }
</script>
```

A page template,

**page.vue**
```vue
<template>
  <div class="page another-page">

    <h1>Radical Page</h1>

  </div>
</template>

<script lang="ts">
  export default {
    components: {

    }
  }
</script>
```

Our header and footer elements,

**header.vue**
```vue
<template>
    <header class="site-header">

      <div class="logo">
        <factor-link path="/"><strong>&Delta;</strong> Factor Site</factor-link>
      </div>

      <div class="links">
        <factor-link path="/">Home</factor-link>
        <factor-link path="/page">Page</factor-link>
        <factor-link path="/dashboard">Dashboard</factor-link>
      </div>

    </header>
</template>

<script lang="ts">
  import { factorLink } from "@factor/ui"
  export default {
    components: {
      factorLink
    }
  }
</script>
```

**footer.vue**
```vue
<template>
  <footer class="site-footer">

      <span>&copy; <strong>&Delta;</strong> Factor Site {{ currentyear() }}</span>

  </footer>
</template>

<script lang="ts">
  import { factorLink } from "@factor/ui"
  import Vue from "vue"
  export default Vue.extend({
    components: {
      factorLink
    },
    data() {
      return {

      }
    },
    methods: {
      currentyear(this: any) {
        return new Date().getFullYear()
      }
    }
  })
</script>
```

And factor will import styles from a file **factor-styles.less**

**factor-styles.less**
```css
.factor-app {
  --color-primary: #0471ff;
  --color-secondary: #ff0076;
  --color-dark: #111111;
  --color-text: #495e6f;
  --font-family-primary: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto",
    "Helvetica Neue", Arial, sans-serif;

  color: var(--color-text);
  font-family: var(--font-family-primary);
  a {
    color: var(--color-primary);
    &:hover {
      color: var(--color-secondary);
    }
  }

  ...
}
```










## Create a Mongo DB <a name="chapter-2"></a>

Now that we have our local server running, it's time to connect Factor to a **Mongo** Database.


Visit [MongoDB Atlas ](https://account.mongodb.com/account/login)


Create an account with Google or an email

![Atlas Sign Up](https://i.ibb.co/YNmW6gt/Factor4.png)


Select 'Build a Cluster'

![Build a Cluster](https://i.ibb.co/dD6fN5G/Factor5.png)


Select Free 'Create a Cluster'

![Create a Cluster](https://i.ibb.co/2cNL4n9/Factor6.png)


Set a unique cluster name,

And select 'Create Cluster'

![Create Cluster](https://i.ibb.co/txx99n4/Factor7.png)


Select 'Continue without upgrading'

![Continue without upgrading](https://i.ibb.co/bsnXrCc/Factor8.png)


Once the cluster has been created,

Select 'Connect'

![Connect](https://i.ibb.co/423TFRX/Factor9.png)


Whitelist your IP Address

Create a Mongo user 'dbuser' with a password, recall this login information for a later step

![Whitelist and Create a Mongo user](https://i.ibb.co/6bRsX1j/Factor10.png)


Select 'Choose a Connection Method'

![Choose a Connection Method](https://i.ibb.co/CPsKYxt/Factor11.png)


Select 'Connect Your Application'

![Connect Your Application](https://i.ibb.co/HPNMdtj/Factor12.png)


### Get Connection String

Select Copy to grab our Mongo DB Connection String

![Copy Connection String](https://i.ibb.co/NtSYy6R/Factor13.png)

Select 'Collections'

![Collections](https://i.ibb.co/bND9Xv4/Factor14.png)


### Add Collections 

Select 'Add my own data'

![Add my own data](https://i.ibb.co/98ncq9q/Factor15.png)


Enter:

Database Name: 'test'
Collection Name:'posts'

![Database Collection name](https://i.ibb.co/Y8d43pF/Factor16.png)







Create a file:
**.env**

And replace the relevant values with your own.

```
FACTOR_ADMINS="adminemail@youremailprovider.com"
TOKEN_SECRET="YOUR-RANDOM-STRING-HERE"

# -- Database - MongoDB/Mongoose compatible connection URL
DB_CONNECTION=mongodb+srv://dbuser:YOUR-COMPLICATED-PASS@unique-cluster-name-4185-dlnjs.mongodb.net/test?retryWrites=true&w=majority

# -- Email - Transactional
# SMTP_USERNAME=""
# SMTP_PASSWORD=""
# SMTP_HOST=""

# -- Production URL
# FACTOR_URL=""


```


In the terminal,

Press Ctrl-C to terminate the server and restart with:

```
npx factor dev
```


## Create Admin User <a name="chapter-3"></a>

In the Browser click on the 'Dashboard' link in the menu

![dashboard](https://i.ibb.co/LYKYVkc/Factor17-A.png)

We will now create the primary admin account

Select 'sign up'

![dashboard](https://i.ibb.co/jwF4pwd/Factor17-B.png)


Enter your Name, 

Enter your email 

***Use the admin email you have specified in the .env file***

![sign up](https://i.ibb.co/yqj4fBH/Factor17-C.png)


You should recieve the success screen:

![sign up](https://i.ibb.co/tKQtPrG/Factor18.png)





## Verify Admin User <a name="chapter-4"></a>

The step above should have generated some output in the terminal

Look for the Verify Email link and copy into your Browser

![sign up](https://i.ibb.co/WG8XRkS/Factor19.png)


Congratulations! Your admin user is now verified.

![sign up](https://i.ibb.co/Cm0jw2s/Factor20.png)

Stay tuned for Part 2 where we explore Posts, Pages and Custom Post Types.

--------------

Download the full source for this tutorial here:

https://github.com/happyrobotstudio/factor-tute-1