Thu Apr 27 2023

Setup a blog with Nuxt

A guide to building up a simple blog with nuxt content, styled with tailwindcss and deploy to netlify

I've always wanted to get back to writing after several years hiatus. Every time I get down to it, I stop at getting a nice theme that is minimal but with the right set of features. I'm not a design and if you ask my colleagues they'd give me a very low rating when it comes to matters design. This time I decided not to overthink it, start with something and improve it over time: "If you are not ashamed of you mvp you launched it too late". With that I challenged myself to ship out something within an hour.

My Stack

  • Nuxt: Nuxt - a web framework built on top of vue - enables development of fast rendering, seo optimized websites. Using nuxt/content, I can write my posts in markdown with vue components, use a file based cms and deploy to either static or node server hosting. It also has several plugins that would come in handy in adding different functionality to my blog as I go along
  • Tailwindcss: A utility-first css framework which allows me to be able to write css within my html. I picked a free theme from Zerostatic which had a minimal that fit my needs
  • Netlify: I want to add auto deploy from github without too much configuration. Netlify also offers edge functions which might come in handy when I need to add server based functionality

The Steps

Create a new nuxt project

npx nuxi@latest init blog
cd blog
npm install
npm run dev

Install nuxt-content

npm install -S @nuxt/content

update nuxt.config.ts

export default defineNuxtConfig({
    modules: [ '@nuxt/content' ]
})

update app.vue

<template>
  <div class="">
    <NuxtLayout>
      <NuxtPage />
    </NuxtLayout>
  </div>
</template>

Create catch all page pages/[...slug].vue

<template>
  <main>
    <ContentDoc />
  </main>
</template>

Add first post content/my-first-post.md

# My First Post

This is my first blog post

List posts on the frontend by creating pages/index.vue


<template>
  <main>
    <h1>Welcome To My Blog</h1>
    <div>
      <ContentNavigation v-slot="{ navigation }">
        <ul>
          <li v-for="link of navigation" :key="link._path">
            <NuxtLink :to="link._path">{{ link.title }}</NuxtLink>
          </li>
        </ul>
      </ContentNavigation>
    </div>
  </main>
</template>

Add tailwind

npm install -D @nuxtjs/tailwindcss  @tailwindcss/typography

update nuxt.config.ts

modules: [
  '@nuxt/content',
  '@nuxtjs/tailwindcss',
]

create tailwind.config.ts

import type { Config } from 'tailwindcss'
import tailwindTypography from '@tailwindcss/typography'

export default <Partial<Config>>{
    plugins: [tailwindTypography]
}

update pages/[...slug].vue

<template>
  <main>
    <ContentDoc tag="article" class="prose prose-slate prose-lg"/>
  </main>
</template>

Add sitemap

npm install -D sitemap

Create server/routes/sitemap.xml.ts

import { serverQueryContent } from '#content/server'
import { SitemapStream, streamToPromise } from 'sitemap'

export default defineEventHandler(async (event) => {
    // Fetch all documents
    const docs = await serverQueryContent(event).find()
    const sitemap = new SitemapStream({
        hostname: process.env.URL
    })
    docs.forEach(doc => sitemap.write({ url: doc._path, changefreq: 'monthly' }))
    sitemap.end()
    return streamToPromise(sitemap)
})

This assumes that your blog url is available in process.env.URL. In your local dev you can add a .env file and add set URL=http://localhost:3000

Deploy to Netlify

To deploy to netlify simply push to github or gitlab then login to netlify, create a new site, link to your repository and update the settings(in our case the defaults work ok) and deploy.

Next Steps

There's still so much to do to get this blog fully functional. Some of the things I'm thinking of at the moment are:

  • Add SEO and social media tags
  • Add pagination, category pages and error pages
  • Setting up analytics(deeper understand how to serve you best)
  • Add vitest so we can test key features before deploying
  • Use nuxt-image for optimizing images and use a cdn
  • Have condensed(tldr) version of tutorial posts where you can just pick the final steps and get going, no need to run installs 10 times

Have you tried setting up a blog or personal website? What's your experience been like? Any tips, ideas, feedback you'd like to share? Let's engage some more on twitter

Categories

githubtwitterlinkedin