Create a new theme from scratch
In this recipe, we will create a new theme from scratch. We will (re)create the theme called "Minimalist" that is included in the Bloggrify core repository.
Getting Started
First, you need to create a new Nuxt application. You can do this by running the following command:
npx nuxi@latest init neo-minimalist
Then, you need to install the dependencies:
npm install @bloggrify/core
npm install -D sass-embedded
Then you have to explicitly say to Nuxt that you are using Bloggrify as an extended module. You can do this by adding the following line in your nuxt.config.js
file:
extends: [
'@bloggrify/core',
],
Create a basic configuration file
Create a new file called app.config.ts
in the root of your project. This file will contain the configuration of your theme.
This file will override the default configuration of Bloggrify. If you don't specify a configuration, the default configuration will be used.
Here is an example of a basic configuration file:
export default defineAppConfig({
url: 'https://neo-minimalist.bloggrify.com/',
theme: 'neo-minimalist',
name: 'Neo-minimalist Demo',
description:
'A minimalist theme for Bloggrify',
})
That's probably not enough for a complete theme, but it's a good start. You can add more configuration options later. Don't forget to read the official documentation to know more about the configuration options.
Create the layout for the home page
Create a new folder called components/themes/neo-minimalist
in the root of your project. This folder will contain the components of your theme.
Create a new file called home.vue
in the components/themes/neo-minimalist
folder. This file will be the layout for the home page.
Here is an example of a basic layout file:
<template>
<div>
<header>
<h1>
{{ title }}
</h1>
</header>
<main>
<div>
<div >
{{ description }}
</div>
<div >
<NuxtLink to="/archives">
Read all posts
</NuxtLink>
</div>
</div>
</main>
</div>
</template>
<script setup lang="ts">
defineProps<{
doc: unknown;
docs: unknown;
currentPage: number;
total: number;
category: string;
tag: string;
}>()
const config = useAppConfig()
const title = config.name
const description = config.description
</script>
Let's explain the code above:
- The
<template>
section contains the HTML structure of the layout. In this example, we have a navigation bar and a main content area. - The
<script setup>
section contains the logic of the layout. In this example, we get the configuration from theapp.config.ts
file and display the title of the blog. - The
ContentRenderer
component is a custom component from Nuxt Content that renders the content of the page. - The defined props are used to pass data to the layout.
All the props are passed by the Bloggrify core package.
Bloggrify first try to find the type of the page among the following types:
categories
: if the url is/categories/something/page/2
tags
: if the url is/tags/something/page/2
archives
: if the url is/archives/page/2
'standard
: for all other pages
Then, it passes the following props to the layout:
doc
: The current document (article)docs
: The list of documents (articles). Not relevant for standard pagescurrentPage
: The current page number. Not relevant for standard pagestotal
: The total number of pages. Not relevant for standard pagescategory
: The current category. Not relevant for standard pagestag
: The current tag. Not relevant for standard pages
Create the index page
Create a new folder called content
in the root of your project. This folder will contain the articles of your blog and the index page.
Create a new file called index.md
in the pages
folder. This file will be the index page of your blog.
---
id: "1"
title: "Home page"
description: "Basic home page"
date: "2024-12-31"
categories:
- home
tags:
- lorem
- ipsum
layout: home
listed: false
---
Run the development server
You can now start the development server by running the following command:
npm run dev
Go to http://localhost:3000
in your browser, and you should see the home page of your blog.
This is cool, but, you don't have the list of all the articles. Let's add a new layout for the archives page.
Create the layout for the archives page
Create a new file called archive.vue
in the layouts/themes/neo-minimalist
folder. This file will be the default layout for the archive page.
Here is an example of a basic layout file:
<template>
<div>
<header>
<h1>
{{ title }}
</h1>
</header>
<main>
<div>
<div >
All Posts
</div>
<div >
<section class="mt-10">
<div v-for="article in docs" :key="article._path">
<NuxtLink :to="article._path">
{{ article.date }} - {{ article.title }}
</NuxtLink>
</div>
</section>
</div>
</div>
</main>
</div>
</template>
<script setup lang="ts">
defineProps<{
doc: unknown;
docs: unknown;
currentPage: number;
total: number;
category: string;
tag: string;
}>()
const config = useAppConfig()
const title = config.name
</script>
This layout will display the list of all the articles. The docs
prop contains the list of all the articles.
Now, you can go to http://localhost:3000/archives
in your browser, and you should see the list of all the articles.
The list is probably empty, because you don't have any articles yet. Let's add some content.
Create the layout
Create a new file called default.vue
in the layouts/themes/neo-minimalist
folder. This file will be the default layout for all pages.
Here is an example of a basic layout file:
<template>
<div>
<header>
<h1>
{{ title }}
</h1>
</header>
<main>
<div v-if="doc">
<div >
<h2>
{{ doc.title }}
</h2>
</div>
<ContentRenderer
id="nuxtContent"
:value="doc"
/>
</div>
</main>
</div>
</template>
<script setup lang="ts">
defineProps<{
doc: unknown;
docs: unknown;
currentPage: number;
total: number;
category: string;
tag: string;
}>()
const config = useAppConfig()
const title = config.name
</script>
Add some content
You can read the official documentation to know more about how to write articles.
But for now, you can create a new file called hello-world.md
in the content
folder with the following content:
---
title: Hello World
description: A simple article to say hello to the world
---
# Hello World
This is a simple article to say hello to the world.
Now, you can go to http://localhost:3000/hello-world
in your browser, and you should see the article.
And voilà, you have created a new theme from scratch! You can now start customizing it to fit your needs. (it's probably ugly, but it's a start :) )