The Release Candidate version of Nuxt 3 dropped out of nowhere! The official release was rescheduled few times but we finally have it so it would be awesome to dive deeper into what it brings to the Nuxt ecosystem. And this is exactly what me and @alvarosabu did during our most recent video colaboration that I highly recommend you to check out with a link below:
In this article, I will summarize each step that we have taken in the video with a written examples and step by step guide. Enjoy!
If you get lost at some point, you can always check out the following github repository:
https://github.com/alvarosabu/nuxt-modules-clone
Nuxt 3
The first step is to generate new project using:
npx nuxi init nuxt-modules-clone
This will generate a default Nuxt 3 project. Let's try to test the newest addition to the ecosystem which is the support for Static Site Generation. In nuxt.config.ts
add following line:
export default defineNuxtConfig({
ssr: false, // <-
})
Now, let's build the project with the following command:
yarn generate
Finally, if we serve the generated static HTML files with the following command:
serve .output/public
*serve is an addition to VS Code that allows to serve static files with local server
We should now see the same result as with yarn dev
in the broweser. Awesome!
TailwindCSS
We now how to generate a static HTML page. Now, let's add a bit of styling into it to make it look a bit better. We will install TailwindCSS by using the official Nuxt module and style some parts of the application.
The installation of the module is relatively simple. Just use the following command:
yarn add --dev @nuxtjs/tailwindcss
And register the module in nuxt.config.ts
in the modules array:
export default defineNuxtConfig({
modules: ['@nuxtjs/tailwindcss'] // <-
})
From now on, you can use the TailwindCSS across your application. We will create a TheHeader.vue
component by using the official Nuxt 3 CLI method:
npx nuxi add component TheHeader
And add a bit of styling into it:
<script lang="ts" setup></script>
<template>
<header class="bg-white py-4 shadow-lg">
<div class="container mx-auto">
<a href="" class="flex items-center"> <img class="h-8 w-8 mr-4" src="/logo.svg" /> Nuxt Module</a>
</div>
</header>
</template>
<style scoped></style>
Inside /public/logo.svg
add following svg code:
<svg width="40" height="40" viewBox="0 0 70 70" fill="none" xmlns="http://www.w3.org/2000/svg" alt="Nuxt"><path d="M31.4918 17.1505C29.8172 14.2712 25.6308 14.2712 23.9562 17.1505L5.70589 48.5305C4.03131 51.4099 6.12453 55.009 9.4737 55.009H23.7209C22.2898 53.7583 21.7598 51.5946 22.8428 49.7382L36.6648 26.0451L31.4918 17.1505Z" fill="#80EEC0"></path><path d="M43.0556 24.0338C44.4415 21.678 47.9061 21.678 49.292 24.0338L64.3957 49.7083C65.7816 52.0641 64.0493 55.0089 61.2775 55.0089H31.0701C28.2984 55.0089 26.566 52.0641 27.9519 49.7083L43.0556 24.0338Z" fill="#00DC82"></path></svg>
Finally, we can use our new TheHeader
component inside our app.vue
<template>
<TheHeader />
</template>
Storyblok
To add content into our page we will use Storyblok CMS.
Let's install the required dependencies by typing following command:
yarn add @storyblok/vue
yarn add --dev axios
In order to make Storyblok work, we will use a Nuxt plugin. Create /plugins/storyblok.ts
file and add following code into it:
import {
StoryblokVue, apiPlugin
} from '@storyblok/vue';
export default defineNuxtPlugin(nuxtApp => {
const config = useRuntimeConfig().public
nuxtApp.vueApp.use(StoryblokVue, {
accessToken: config.apiToken,
use: [apiPlugin]
});
})
*Remember to create a .env file with an access token grabbed from Storyblok.
Let's add storyblok token to runtimeConfig:
export default defineNuxtConfig({
runtimeConfig: {
public: {
apiToken: process.env.STORYBLOK_TOKEN
}
},
})
Now, let's create a ModuleCard
component that we will use to show each module:
<script lang="ts" setup>
const props = defineProps({
name: {
type: String,
default: "Module Card"
},
description: {
type: String,
default: "Crazy description"
},
icon: {
type: Object,
default: () => ({})
},
url: {
type: Object,
default: () => ({})
}
})
</script>
<template>
<a class="flex justify-center" :href="url.url">
<div class="flex items-center p-8 flex-col md:flex-row md:max-w-xl rounded-lg bg-white shadow-lg">
<img class="w-10 h-10 object-fit" :src="icon.filename" :alt="icon.alt" />
<div class="px-8 flex flex-col justify-start">
<h5 class="text-gray-900 text-xl font-medium mb-2">{{name}}</h5>
<p class="text-gray-700 text-base mb-4">
{{description}}
</p>
</div>
</div>
</a>
</template>
<style scoped></style>
Finally, let's use all before created parts in our app.vue
root page:
<script setup lang="ts">
import { useStoryblokApi } from "@storyblok/vue";
const storyblokApi = useStoryblokApi();
const { data } = await storyblokApi.get("cdn/stories", { version: "draft", starts_with: 'modules' });
const modules = computed(() => data.stories);
</script>
<template>
<TheHeader />
<div class="container mx-auto p-8 grid grid-cols-1 md:grid-cols-3 gap-4">
<ModuleCard v-for="module in modules" v-bind="module.content" />
</div>
</template>
Vercel
The whole configuration of Vercel is well defined in the video so I will just summarize it.
Import github repository in Vercel
Define proper build command:
Build command should be yarn generate
and output folder .output/public
Finally, add Storyblok token as Environment Variable:
If all went well with the configuration, you should see similar result as our demo https://nuxt-modules-clone.vercel.app/
Summary
Well done! You have just created a simple Nuxt Modules clone with Nuxt 3 SSG, TailwindCSS, Storyblok, and Vercel. We covered a lot in this article so take a little brake and then get back to the topic as there is much more to discover!
Bonus
Below, I am posting some links that might be useful for you:
Top comments (0)