Static Site using Nuxt.js with Storyblok CMS
Tags: nuxt, storyblok, staticsite, javascript
Published: 2022-05-25 15:54:18

## You want to build fast and secure website? 

This guide show how to develop full-blown website using Nuxt.js, Storyblok and Tailwind CSS. 

### Introduction

**What is Jamstack?

Jamstack is an architecture designed to make the web faster, more secure, and easier to scale. It builds on many of the tools and workflows which developers love, and which bring maximum productivity.

- Better Performance

- Higher Security

- Cheaper, Easier Scaling

- Better Developer Experience

**Site Generators**

**Nuxt.js **is a free and open source JavaScript library based on Vue.js,

BTW: Easy to learn. Easy to master, Zero Configuration, SEO friendly

**Headless CMS**

A headless CMS is any type of back-end content management system where the content repository “body” is separated or decoupled from the presentation layer “head.” Content that is housed in a headless CMS is delivered via APIs for seamless display across different devices.

**StoryBlok**

The first component-based headless CMS with Visual Editor.


### Let's Start coding 

Installation

Requirement

```
Nuxt.js v2.14.0
Nodejs v12.3.1
Npm v6.9.0
```

```
yarn create nuxt-app my-nuxt-app // npx create-nuxt-app my-nuxt-app
cd my-nuxt-app
yarn dev // npm run dev

```
I prefer yarn. 

Install Storyblok package.

```
yarn add @storyblok/nuxt //for nuxt v3
yarn add  @storyblok/nuxt-2 //for nuxt-2
```

Next step is add to nuxt module in  nuxt.config.js 



```
['@storyblok/nuxt/module', { accessToken: process.env.YOUR_STORYBLOK_API_KEY }],

```

To get this stroyblok API key get to your space in Storyblok and copy the preview api key.


**From Storyblok side
**
1. Create Space in Storyblok
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e5c8851gikt8y3p57sfa.png)

2. Create component
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e64mf8xaepgclkb1g2uy.png)

3. Define component schema
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v0u1amijjgndjqheydfe.png)


In the Code(Nuxt.js)

Create Page component in `components/Page.vue`
```
<template>
  <div
    v-editable="blok"
    class="px-6">
    <component
      v-for="blok in blok.body"
      :key="blok._uid"
      :blok="blok"
      :is="blok.component" />
  </div>
</template>
 
<script>
export default {
  props: {
    blok: {
      type: Object,
      required: true
    }
  }
}
</script>
```

To make access component to globaly
Add component to  `plugins/components.js`

```
import Page from '~/components/Page.vue'

Vue.component('Page', Page)
```

Then add this plugin to nuxt.config

```
plugins: ['~/plugins/components']
```


Let's create index page and fetch the content from Storyblok

```
<template>
  <div>
    <component :is="story.content.component" v-if="story.content.component" :key="story.content._uid" :blok="story.content" />
  </div>
</template>

<script>
import { useStoryblokBridge } from '@storyblok/nuxt'

export default {
  middleware: 'fetchGlobalLayout',
  asyncData: (context) => {
    const version = context.query._storyblok || context.isDev ? 'draft' : 'published'
    
    const language = context.app.i18n.locale // this i18n, i will get back this. 

    return context.app.$storyapi
      .get('cdn/stories/home', {
        language,
        version,
      })
      .then((res) => {
        return res.data
      })
      .catch((res) => {
        if (!res.response) {
          context.error({
            statusCode: 404,
            message: 'Failed to receive content from api',
          })
        } else {
          context.error({
            statusCode: res.response.status,
            message: res.response.data,
          })
        }
      })
  },
  
  mounted() {
    useStoryblokBridge(this.story.id, (newStory) => (this.story = newStory))
  },
}
</script>
```






## To be continued