diff --git a/.contentful.sample.json b/.contentful.sample.json
index dec5eef..20965ff 100644
--- a/.contentful.sample.json
+++ b/.contentful.sample.json
@@ -1,6 +1,4 @@
 {
-  "CTF_PERSON_ID": "15jwOBqpxqSAOy2eOO4S0m",
-  "CTF_BLOG_POST_TYPE_ID": "blogPost",
   "CTF_SPACE_ID": "SPACE_ID",
   "CTF_CDA_ACCESS_TOKEN": "CDA_ACCESS_TOKEN",
   "CTF_CMA_ACCESS_TOKEN": "CMA_ACCESS_TOKEN"
diff --git a/components/article-preview.vue b/components/article-preview.vue
index c471ab1..7dac2f8 100644
--- a/components/article-preview.vue
+++ b/components/article-preview.vue
@@ -6,7 +6,7 @@
       sizes="(min-width: 1024px) 400px, 100vw"
     >
     <time class="tiny date">{{ ( new Date(post.fields.publishDate)).toDateString() }}</time>
-    <span class="tiny">– Posted in {{ post.fields.category }}</span>
+    <span class="tiny">– Posted in <nuxt-link :to="{ name: 'categories-category', params: { category: post.fields.category_ref.fields.slug }}" class="tiny">{{ post.fields.category_ref.fields.name }}</nuxt-link></span>
     <h4><nuxt-link :to="{ name: 'blog-slug', params: { slug: post.fields.slug }}" class="title">{{ post.fields.title }}</nuxt-link></h4>
     <p>{{ post.fields.description }}</p>

diff --git a/config.json b/config.json
new file mode 100644
index 0000000..dff9f14
--- /dev/null
+++ b/config.json
@@ -0,0 +1,5 @@
+{
+  "CTF_PERSON_ID": "15jwOBqpxqSAOy2eOO4S0m",
+  "CTF_BLOG_POST_TYPE_ID": "blogPost",
+  "CTF_CATEGORY_TYPE_ID": "category"
+}
diff --git a/layouts/default.vue b/layouts/default.vue
index 4788cc5..7c353a6 100644
--- a/layouts/default.vue
+++ b/layouts/default.vue
@@ -41,6 +41,7 @@
   }

   .blog.header h2,
+  .category-page.header h2,
   .tag-page.header h2 {
     text-align: center;
     padding: 2.5em 0;
-diff --git a/components/article-preview.vue b/components/article-preview.vue
-index 444f24e..c471ab1 100644
---- a/components/article-preview.vue
-+++ b/components/article-preview.vue
-@@ -6,6 +6,7 @@
-       sizes="(min-width: 1024px) 400px, 100vw"
-     >
-     <time class="tiny date">{{ ( new Date(post.fields.publishDate)).toDateString() }}</time>
-+    <span class="tiny">– Posted in {{ post.fields.category }}</span>
-     <h4><nuxt-link :to="{ name: 'blog-slug', params: { slug: post.fields.slug }}" class="title">{{ post.fields.title }}</nuxt-link></h4>
-     <p>{{ post.fields.description }}</p>
-
-diff --git a/layouts/default.vue b/layouts/default.vue
-index 5b1a55a..4788cc5 100644
---- a/layouts/default.vue
-+++ b/layouts/default.vue
-@@ -1,22 +1,11 @@
- <template>
-   <div class="container">
--    <Greeting></Greeting>
-     <main role="main">
-       <nuxt/>
-     </main>
-   </div>
- </template>
-
--<script>
--  import Greeting from '~/components/greeting.vue'
--
--  export default {
--    components: {
--      Greeting
--    }
--  }
--</script>
--
- <style>
-   @font-face {
-     font-family: "Avenir";
-diff --git a/pages/blog/_slug.vue b/pages/blog/_slug.vue
-index e9ef0bb..94dcbd8 100644
---- a/pages/blog/_slug.vue
-+++ b/pages/blog/_slug.vue
-@@ -21,6 +21,7 @@
-       <main class="wrapper">
-         <div class="headline">
-           <time class="tiny">{{ ( new Date(post.fields.publishDate)).toDateString() }}</time>
-+          <span class="tiny">– Posted in {{ post.fields.category }}</span>
-           <h1>{{ post.fields.title }}</h1>
-         </div>
-         <div class="copy">
diff --git a/nuxt.config.js b/nuxt.config.js
index ebe0df6..5bca488 100644
--- a/nuxt.config.js
+++ b/nuxt.config.js
@@ -1,11 +1,10 @@
 const {getConfigForKeys} = require('./lib/config.js')
 const ctfConfig = getConfigForKeys([
-  'CTF_BLOG_POST_TYPE_ID',
   'CTF_SPACE_ID',
   'CTF_CDA_ACCESS_TOKEN',
-  'CTF_CMA_ACCESS_TOKEN',
-  'CTF_PERSON_ID'
+  'CTF_CMA_ACCESS_TOKEN'
 ])
+const blogModel = require('./config.json')
 const {createClient} = require('./plugins/contentful')
 const cdaClient = createClient(ctfConfig)
 const cmaContentful = require('contentful-management')
@@ -75,6 +74,7 @@ const config = {
   **
   ** Included:
   ** - blog posts
+  ** - categories
   ** - available blog post tags
   */
   generate: {
@@ -82,16 +82,22 @@ const config = {
       return Promise.all([
         // get all blog posts
         cdaClient.getEntries({
-          'content_type': ctfConfig.CTF_BLOG_POST_TYPE_ID
+          'content_type': blogModel.CTF_BLOG_POST_TYPE_ID
+        }),
+        // get all categories
+        cdaClient.getEntries({
+          'content_type': blogModel.CTF_CATEGORY_TYPE_ID
         }),
         // get the blog post content type
         cmaClient.getSpace(ctfConfig.CTF_SPACE_ID)
           .then(space => space.getContentType(ctfConfig.CTF_BLOG_POST_TYPE_ID))
       ])
-      .then(([entries, postType]) => {
+      .then(([entries, categories, postType]) => {
         return [
-          // map entries to URLs
+          // map posts to URLs
           ...entries.items.map(entry => `/blog/${entry.fields.slug}`),
+          // map categories to URLs
+          ...categories.items.map(entry => `/categories/${entry.fields.slug}`),
           // map all possible tags to URLs
           ...postType.fields.find(field => field.id === 'tags').items.validations[0].in.map(tag => `/tags/${tag}`)
         ]
@@ -106,8 +112,9 @@ const config = {
   env: {
     CTF_SPACE_ID: ctfConfig.CTF_SPACE_ID,
     CTF_CDA_ACCESS_TOKEN: ctfConfig.CTF_CDA_ACCESS_TOKEN,
-    CTF_PERSON_ID: ctfConfig.CTF_PERSON_ID,
-    CTF_BLOG_POST_TYPE_ID: ctfConfig.CTF_BLOG_POST_TYPE_ID
+    CTF_PERSON_ID: blogModel.CTF_PERSON_ID,
+    CTF_BLOG_POST_TYPE_ID: blogModel.CTF_BLOG_POST_TYPE_ID,
+    CTF_CATEGORY_TYPE_ID: blogModel.CTF_CATEGORY_TYPE_ID
   }
 }

diff --git a/pages/blog/_slug.vue b/pages/blog/_slug.vue
index 94dcbd8..517cad2 100644
--- a/pages/blog/_slug.vue
+++ b/pages/blog/_slug.vue
@@ -21,7 +21,7 @@
       <main class="wrapper">
         <div class="headline">
           <time class="tiny">{{ ( new Date(post.fields.publishDate)).toDateString() }}</time>
-          <span class="tiny">– Posted in {{ post.fields.category }}</span>
+          <span class="tiny"> – Posted in <nuxt-link :to="{ name: 'categories-category', params: { category: post.fields.category_ref.fields.slug }}" class="tiny">{{ post.fields.category_ref.fields.name }}</nuxt-link></span>
           <h1>{{ post.fields.title }}</h1>
         </div>
         <div class="copy">
@@ -47,7 +47,7 @@ export default {
       'fields.slug': params.slug
     }).then(entries => {
       return {
-        post: entries.items[0]
+        post: client.parseEntries(entries).items[0]
       }
     })
     .catch(console.error)
diff --git a/pages/blog/index.vue b/pages/blog/index.vue
index b33fdaf..bd81d88 100644
--- a/pages/blog/index.vue
+++ b/pages/blog/index.vue
@@ -40,7 +40,7 @@ export default {
       order: '-sys.createdAt'
     }).then(entries => {
       return {
-        posts: entries.items
+        posts: client.parseEntries(entries).items
       }
     })
   },
diff --git a/pages/categories/_category.vue b/pages/categories/_category.vue
new file mode 100644
index 0000000..2ef6a71
--- /dev/null
+++ b/pages/categories/_category.vue
@@ -0,0 +1,74 @@
+<template>
+  <div>
+    <header class="category-page header">
+      <div class="foreground">
+        <div class="page-bar wrapper">
+          <a href="/" class="person-name">John Doe</a>
+          <Navigation></Navigation>
+        </div>
+        <div class="page-info wrapper" :style="{ backgroundImage: 'url(' + categoryImageUrl + ')' }">
+          <h2 :style="{ color: (categoryImageUrl ? 'white' : '#a0a0a0') }">{{ categoryName }} category</h2>
+        </div>
+      </div>
+    </header>
+
+    <section class="body-container">
+      <div class="items-bar wrapper">
+        <h2>All articles from <em>{{ categoryName }}</em> ({{ posts.length }})</h2>
+      </div>
+      <ul class="items-list wrapper">
+        <li class="item" v-for="post in posts">
+          <article-preview :post="post"></article-preview>
+        </li>
+      </ul>
+    </section>
+  </div>
+</template>
+
+<script>
+import {createClient} from '~/plugins/contentful.js'
+import Navigation from '~/components/navigation.vue'
+import ArticlePreview from '~/components/article-preview.vue'
+
+const client = createClient()
+
+export default {
+  asyncData ({ env, params }) {
+    return Promise.all([
+      client.getEntries({
+        'content_type': env.CTF_BLOG_POST_TYPE_ID,
+        'fields.category_ref.sys.contentType.sys.id': env.CTF_CATEGORY_TYPE_ID,
+        'fields.category_ref.fields.slug': params.category,
+        order: '-sys.createdAt'
+      }),
+      client.getEntries({
+        'content_type': env.CTF_CATEGORY_TYPE_ID,
+        'fields.slug': params.category
+      })
+    ]).then(([posts, categories]) => {
+      posts = client.parseEntries(posts)
+      var category = client.parseEntries(categories).items[0]
+      return {
+        posts: posts.items,
+        categoryName: category.fields.name,
+        categoryImageUrl: (category.fields.image ? category.fields.image.fields.file.url : '')
+      }
+    })
+  },
+  components: {
+    ArticlePreview,
+    Navigation
+  }
+}
+</script>
+
+  <style>
+    .category-page .page-info {
+      -ms-background-size: cover;
+      -o-background-size: cover;
+      -moz-background-size: cover;
+      -webkit-background-size: cover;
+      background-size: cover;
+      background-position: center center;
+    }
+  </style>
diff --git a/pages/index.vue b/pages/index.vue
index 983925b..bc8f3a6 100644
--- a/pages/index.vue
+++ b/pages/index.vue
@@ -34,6 +34,15 @@
     </header>

     <section class="body-container">
+
+      <nav class="wrapper category-list">
+        <span class="tiny">Categories:</span>
+        <nuxt-link
+          v-for="category in categories" :key="category.sys.id"
+          :to="{ name: 'categories-category', params: { category: category.fields.slug }}"
+          class="tiny" style="margin: 0 .3rem">{{category.fields.name}}</nuxt-link>
+      </nav>
+
       <div class="items-bar wrapper">
         <h2>Recent articles</h2>
       </div>
@@ -63,11 +72,15 @@ export default {
       client.getEntries({
         'content_type': env.CTF_BLOG_POST_TYPE_ID,
         order: '-sys.createdAt'
+      }),
+      client.getEntries({
+        'content_type': env.CTF_CATEGORY_TYPE_ID
       })
-    ]).then(([entries, posts]) => {
+    ]).then(([entries, posts, categories]) => {
       return {
         person: entries.items[0],
-        posts: posts.items
+        posts: client.parseEntries(posts).items,
+        categories: categories.items
       }
     }).catch(console.error)
   },
@@ -122,6 +135,11 @@ export default {
   width: 150%;
 }

+.category-list {
+  padding: .5rem 0;
+  text-align: left;
+}
+
 @media all and (min-width: 600px) {
   .picture {
     left: 20%;
