Skip to main content

Site creation

Follow the steps taken to create this Docusaurus blog. Learn about using essential plugins like search, sitemap, image zoom, and adding the Giscus comment system.

· 8 min read
View raw
Christophe
Markdown, WSL and Docker lover ~ Insatiable curious.
Cet article existe aussi en français — lire la version française.

This article is over a year old but was reviewed on July 30, 2026 — the content is still accurate.

Docusaurus.io

Creation of this blog

⚡
TL;DR

This article documents how this blog was built: bootstrapping Docusaurus in blog-only mode entirely through the official Docker node image (no local Node.js install), configuring docusaurus.config.js, and adding plugins for local search, sitemap, image zoom, and Giscus comments. It ends with building the static site via yarn build and deploying it over FTP with WinSCP, plus injecting a GDPR-compliant analytics script from withcabin.com.

Here are the steps I followed to create this blog.

Using Docusaurus​

Since I really like the simplicity of Docker, I will not install Node.js on my machine but use the official Docker image. This article shows the raw docker run approach; if you prefer a ready-made Dockerfile and a compose.yaml, jump to Running Docusaurus with Docker.

Your values for this page
default
default
Applies to the commands on this pageSaved on this device only
>user@machine: ~/yourproject

The instruction above will download Node.js (the latest version) on my machine if it is not already present and create a running instance (called a container of it). The flag --user $UID:$GID is used to start the container using the same credentials as my local one (i.e., reuse my local Unix christophe user so files/folders created in the container will be owned by my local user).

The -v ${PWD}/:/project command line argument will share my current folder on my computer with the container that is, the /project folder in the container will be my current folder on my computer.

And finally, I run an interactive shell since I have mentioned /bin/bash as the entry point.

Now that I have a prompt in the container, I will create my blog using Docusaurus (as explained in the official documentation).

>user@machine: ~/yourproject

After a long time, the blog folder is created and I can take a look at its content:

blog
docs
node_modules
src
static

The installation step is now finished; I will exit the container and return to my computer, and to do this, from the Docker console, I just type exit.

Run the website​

Back to my computer, I will now go inside my blog folder (cd blog) and run the Docker command again but this time with the -p 3000:3000 extra parameter. This parameter will expose the port 3000 from the container to my machine so I can see the website by surfing to http://localhost:3000.

Instead of running an interactive shell session I prefer to run /bin/bash -c "npx docusaurus start" to run the Docusaurus watcher and serve my files:

>user@machine: ~/yourproject

After a few seconds, the container is ready to use and I surf to my site by going to http://localhost:3000.

http://localhost:3000

Homepage

The --host 0.0.0.0 flag

It is really crucial to use the --host 0.0.0.0 flag when calling npx docusaurus start. This will allow external access to the website. If missing, browsing to http://localhost:3000 (or running curl http://127.0.0.1:3000) will display an error Empty reply from server.

Some settings​

By default (using the standard installation), Docusaurus will create a skeleton of a website having two main entries: a blog and a tutorial.

To keep things manageable, I will only keep the blog and remove the tutorial part. For this, I have followed this official article: https://docusaurus.io/docs/blog#blog-only-mode.

Now, I can remove the /docs folder from my blog directory:

blog
node_modules
src
static

I will also make some changes to files like docusaurus.config.js or blog/authors.yml to fit my needs.

File docusaurus.config.js​

By setting hideOnScroll to true, the navigation bar will be hidden when the user scrolls down but will be displayed back as soon as they scroll up. Idea is to give more space on the screen for the content.

export default {
themeConfig: {
navbar: {
// auto-hide the navbar when the user will scroll down, show again when scroll up
hideOnScroll: true,
},
},
};

This exports a configuration object that sets up the theme for a documentation or website framework, specifically enabling the navbar to automatically hide when users scroll down and reappear when they scroll back up.

Define the default image for social media:

export default {
themeConfig: {
// Default image when sharing a post on social media
image: 'img/social-card.jpg',
},
};

This file exports a configuration object that sets up theme-related settings. Specifically, it defines a default image that will be used when someone shares a post from this site on social media platforms like Twitter or Facebook.

Make my first article​

With my preferred editor (vscode) I open my blog's website (I just type code . in my Linux console to open my blog project).

Now, in the /blog directory, I create a new folder called 2023-11-02-site-creation and there I create the index.md file.

Note

When my blog post contains only text and no images or linked files, I can just create a .md file like /blog/2023-11-02-this-is-a-test.md. The creation of a folder is therefore not mandatory at all.

In the previous chapter, npx was executed using the docker run --rm -it --name blog --user $UID:$GID -v ${PWD}/:/project -w /project -p 3000:3000 node /bin/bash -c "npx docusaurus start --host 0.0.0.0" command so, any changes made to the blog will be immediately synchronized with Docker meaning, I just need to save my article and npx will reload my site; very easy and convenient.

Using some layouts​

Docusaurus supports some Markdown special tags called admonition (see https://docusaurus.io/docs/markdown-features/admonitions).

For instance, to display a paragraph as a tip, like below, just use the following syntax:

:::tip
Some **content** with _Markdown_ `syntax`.
:::

Information

Some content with Markdown syntax.

To get the entire list of supported features, see Markdown Features.

Adding plugins​

Search engine​

https://github.com/cmfcmf/docusaurus-search-local

The search engine feature has been added by following this blog article: https://yoandev.co/une-documentation-avec-docusaurus-et-gitlab-pages/#bonus--ajoutons-un-moteur-de-recherche

Added by running yarn add @cmfcmf/docusaurus-search-local in the Docker container (opened using make bash).

Support for PHP and bash in prism​

https://www.npmjs.com/package/@docusaurus/theme-classic

Added by running yarn swizzle @docusaurus/theme-classic prism-include-languages in the Docker container (opened using make bash). Read more at Supported Languages.

Sitemap generator​

https://docusaurus.io/docs/api/plugins/@docusaurus/plugin-sitemap

Added by running yarn add @docusaurus/plugin-sitemap in the Docker container (opened using make bash).

When added, I have also manually created the static/robots.txt file with this content:

User-Agent: *
Sitemap: https://www.avonture.be/sitemap.xml
Disallow: /*index.xml$
Disallow: /index.json
Disallow: /search/index.json

This is a robots.txt file that tells search engine crawlers (like Google's bot) what they're allowed to access on the avonture.be website. It allows all crawlers to visit the site, points them to the sitemap for better indexing, but blocks them from accessing a few specific XML and JSON files that are probably internal or administrative resources.

Image plugins​

https://docusaurus.io/docs/api/plugins/@docusaurus/plugin-ideal-image

Added by running yarn add @docusaurus/plugin-ideal-image in the Docker container (opened using make bash). Read more at Supported Languages.

https://www.npmjs.com/package/docusaurus-plugin-image-zoom

Added by running yarn add docusaurus-plugin-image-zoom in the Docker container (opened using make bash).

Adding a comment area​

How to add Giscus comments to Docusaurus

Adding Giscus to allow comments and feedback.

Push to Github​

On Github.com, I have created a new repository called blog (https://github.com/cavo789/blog). Once this is done, back to my console and I run a few git commands:

>user@machine: ~/yourproject

Once this was done, I have thus pushed my files to Github as foreseen by Docusaurus that is, for instance, the /node_modules is not part of my repo; which is fine since we will create that folder later by running some npx command on the web server where the site will be hosted.

Build static version of the blog​

In order to build static pages, I run docker run --rm -it --user $UID:$GID -v ${PWD}/:/project -w /project node /bin/bash -c "yarn build".

This will create/update the /build folder with a fresh version of the site.

The next step is to start my FTP client (which is WinSCP) and copy my local /blog/build folder to my remote website. To only send the files that really changed, see WinSCP - Synchronize host and remote.

Nowadays, I no longer do this by hand: the site is deployed automatically, as explained in GitHub - Use Actions to deploy this blog.

Adding withcabin for GDPR compliant stats​

By adding the lines below to the docusaurus.config.js as child node of const config, I'm injecting a script into the body part. This will then allow GDPR compliant stats on https://withcabin.com/.

scripts: [
{
src: 'https://scripts.withcabin.com/hello.js',
async: true,
defer: true,
},
],

This configuration defines a single external script to be loaded on a webpage. The script comes from an external URL and is configured to load asynchronously and deferred, meaning it won't block the page from rendering while it's being fetched.

Note: the script is only injected to pages after a yarn build that is when the static site is rendered; not during a yarn watch.


Was this article helpful?
Did you try the steps in this article?