Blog
Reference

Theming

Learn how to change the look and feel of your blog.

It is possible to change the look and feel of your blog by changing the theme. By default, Bloggrify comes with the "Minimalist" theme, but you can create your own theme or use a theme created by the community. You can find some templates here.

The theming system use extensively the concept of layers and layouts in Nuxt. A theme extends Bloggrify and brings its own configuration and components.

Structure of a theme

A theme is a Nuxt module. It is a folder that contains :

  • an app/app.config.ts file. The app.config.ts file contains the configuration of the theme.
  • an app/components/themes/MYTHEME folder. The components folder contains the components of the theme.
  • an app/layouts/themes/MYTHEME folder. The layout that can be used into each page.
  • a content folder. It is where you write your articles.
  • an app/assets folder (OPTIONAL). It is where you put your images and other assets (css files, etc.)
  • a public folder (OPTIONAL). It is where you put your static files (like a favicon etc.)

Each theme should have the following components (with the exact same name):

  • app/layouts/themes/MYTHEME/default.vue: The default layout for all pages. Of course you can create other layouts if you want for specific pages (like the home page)

And then you can select the theme in the app/app.config.ts file.

export default defineAppConfig({
    theme: "MYTHEME",
    // ...
})

Create a new theme

To create a new theme, you can either:

  • start from the "Mistral" theme. It is a simple and clean template. You can clone the repository and start modifying it.
  • start from scratch. You can follow the theme creation guide to create your own theme.

This is a nuxt-application so you can benefit from all the features of Nuxt. You can use the Nuxt documentation to help you. But most of the time, you'll only need to modify the files in the app/components folder and the app/app.config.ts file.

Supporting tags and categories

If you want to support tags and categories, you should create the following layouts in your theme:

  • app/layouts/themes/MYTHEME/tag.vue
  • app/layouts/themes/MYTHEME/category.vue

These layouts will be used to display the list of articles for a specific tag or category. You can check the Mistral theme for an example.

Supporting the authors pages

Two layouts back the author pages:

  • app/layouts/themes/MYTHEME/author.vue receives an author prop and displays one author's bio and posts, at /authors/{username}.
  • app/layouts/themes/MYTHEME/authors.vue receives an authors prop (the array from app.config.ts) and lists every author, at /authors. This page is opt-in through authors_page.enabled, see Configuration.

A theme that does not implement one of these returns a 404 for the matching URL.

Custom error page (404)

Bloggrify ships a default error page. It handles 404s (an unknown URL, or a page a theme chose not to implement) and any other error, without leaking internals to the visitor. A theme can replace it with its own by adding:

  • app/layouts/themes/MYTHEME/error.vue

If the theme does not provide one, the framework default is used. The layout receives the error object as a prop. The useErrorPage() composable derives everything you render from it, so the theme only writes markup:

<template>
  <div>
    <p>{{ statusCode }}</p>
    <h1>{{ title }}</h1>
    <p>{{ description }}</p>
    <UButton @click="handleError">Back to home</UButton>
  </div>
</template>

<script setup lang="ts">
import type { NuxtError } from '#app'

const props = defineProps<{ error: NuxtError }>()
const { statusCode, isNotFound, title, description, handleError } = useErrorPage(() => props.error)
</script>

statusCode and title/description are the visitor-safe values (the raw error message is never exposed in production). isNotFound is true for a 404, so you can word a missing-page case differently from a server error. handleError clears the error and returns to the home page.

Copyright © 2026