Creating your first site with Hinode
Posted on April 3, 2023 (Last modified on December 13, 2024) • 13 min read • 2,592 wordsGuide on how to set up your site with version control using npm, GitHub and VSCode.
Note
The commands and code examples within this guide are written with macOS in mind. The commands should be transferrable to Windows and Linux too.
Hinode uses Hugo , a popular open-source generator, to generate a static website. Static websites do not require a database and can be hosted virtually anywhere. In this guide, we will set up a new site using a template from GitHub. We will then edit our Markdown content with Visual Studio Code (VSCode). Lastly, we will submit our changes to the main branch.
This guide requires a GitHub account to host the remote demo repository. Next, Git, Node.js and npm are required for local development and testing. The guide also uses VSCode to edit the content. Click on each of the following links to sign up and install the required software as necessary. The software packages should be compatible with Windows, macOS, and most Linux distributions.
As first step we will create a new repository on GitHub using a template. The template uses npm to automate several tasks. We will then connect our local machine to the remote repository and install the required dependencies. Lastly, we will run a local development server to test the newly created site.
Hinode comes in two flavors: a template and a main theme . We will use the template as starting point for our new site, as it has several predefined settings that support automation. The main repository provides a regular theme that is compatible with Hugo’s module system. It is better suited if you prefer to manually maintain and publish your Hinode site1.
Navigate to the
template repository
in your browser and click on the green button Use this template
to create a new repository. You may need to sign in to GitHub for the button to become available. Provide a meaningful name for your repository, such as hinode-demo
. The repository’s visibility can be either private or public. Public repositories can be seen by anyone, such as open-source projects. Private repositories are only visible to yourself, or to anyone you have granted access. Lastly, click on the green button Create repository from template
to create your repository.
We will now connect our local machine to the newly created GitHub repository. Navigate to a folder in the terminal of your local machine, such as ~/development
2. Use the git clone
command to download and extract your GitHub repository within the current folder. By default, git creates a new subfolder with the name of your repository, e.g. hinode-demo
. The next command is an example, be sure to replace the
{USER} name with your own.
git clone https://github.com/{USER}/hinode-demo.git
Cloning into 'hinode-demo'...
remote: Enumerating objects: 41, done.
remote: Counting objects: 100% (41/41), done.
remote: Compressing objects: 100% (34/34), done.
remote: Total 41 (delta 1), reused 28 (delta 1), pack-reused 0
Receiving objects: 100% (41/41), 126.89 KiB | 21.15 MiB/s, done.
Resolving deltas: 100% (1/1), done.
We will now install the various packages and dependencies used by Hinode. The file packages.json
in the repository root defines the npm packages and their versions as used by Hinode. First, navigate to the hinode-demo
folder:
cd hinode-demo
Next, use the command npm install
to download and install the various packages. npm will store these files in the hinode-demo/node_modules
folder. The script downloads and installs the latest Hugo binary automatically. In this approach, the Hugo binary is linked exclusively to your repository, minimizing potential version conflicts on your local machine.
npm install
added 537 packages, and audited 538 packages in 6s
188 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilities
Lastly, we will install the Hugo modules used by Hinode. Hinode supports two types of modules. Core modules are embedded in the main stylesheet and script bundle, ensuring they are available to all pages across the site. On the other hand, optional modules are only included on a page-by-page basis. For example, if your site only requires an interactive map on a few pages, you can include the Leaflet module on those pages only. This helps to reduce the size of your page assets.
Hinode itself is also a module that is used by the Hinode template. This allows us to use the shortcodes and other components provided by Hinode, without having to worry about their implementation. We can use
Hugo’s module system
to update the used modules to their latest version. Run the script mod:update
to download and install the latest version of the modules.
npm run mod:update
> @gethinode/template@0.11.0 mod:update
> rimraf _vendor && hugo mod get -u ./... && hugo mod get -u && npm run -s mod:vendor && npm run -s mod:tidy
Update module in /../hinode-guide
The mod:update
script requires some explanation. The command is defined in package.json
and references mod:tidy
and mod:vendor
:
"mod:update": "rimraf _vendor && hugo mod get -u ./... && hugo mod get -u && npm run -s mod:vendor && npm run -s mod:tidy",
"mod:tidy": "hugo mod tidy",
"mod:vendor": "rimraf _vendor && hugo mod vendor",
The update command chains several commands that each need to run successfully (hence the &&
instructions). Click on each separate command to reveal the context.
npm run -s mod:vendor
). To avoid synchronization issues, the _vendor
folder is purged prior to each module update.go mod get
behind the scenes to download and install the required modules, taking version requirements into account. The -u
flag requests Hugo to update the modules to their latest version too. The ./...
argument instructs Hugo to update all modules recursively. This includes the exampleSite
subfolder, if any.go.mod
file in the repository root when updating any module files in subfolders (such as exampleSite
). Running hugo mod get -u
without the recursive argument is a workaround to fix this../_vendor
). Vendoring is also required when you have a subsite, such as exampleSite
, or if you would like to reference a specific file from a module (using for example the
docs shortcode ).hugo mod tidy
removes unused entries in go.mod
and go.sum
.Your site is now ready for testing. Enter the following command to start a local development server:
npm run start
> @gethinode/template@0.11.0 prestart
> npm run -s mod:vendor
> @gethinode/template@0.11.0 start
> hugo server --bind=0.0.0.0 --disableFastRender --printI18nWarnings
Watching for changes in /../hinode-demo/{..}
Watching for config changes in [..]
Start building sites ...
hugo v0.117.0+extended darwin/arm64
| EN
-------------------+------
Pages | 6
Paginator pages | 0
Non-page files | 0
Static files | 104
Processed images | 11
Aliases | 0
Sitemaps | 1
Cleaned | 0
Built in 1311 ms
Environment: "development"
Serving pages from memory
Web Server is available at http://localhost:1313/ (bind address 0.0.0.0)
Press Ctrl+C to stop
It usually takes less than a minute to build the site and to start the web server in development mode. Before building the site, Hinode cleans several folders. The build itself shows the result of the pages and other assets generated by Hugo. By default, the starter web site supports the English (EN
) language. Lastly, Hugo mentions the local address on which it is available (usually http://localhost:1313/
) and indicates the folders it is watching. The latter means that if you make any changes whilst the web server is running, Hugo should pick up those changes and regenerate the applicable assets. Using a feature called live reloading, your web browser will be instructed to refresh the web page accordingly.
We will now use VSCode to modify the content of our demo site. Start the application and open the hinode-demo
folder. The explorer view provides an overview of the folders and files of the repository. The key folders are the following:
Folder | Description |
---|---|
assets |
Contains static files such as images and stylesheets that are processed by Hugo during build. |
config |
Defines the configuration of the site. |
content |
Maintains the content and its translations of the site. |
layouts |
Defines Hugo shortcodes and partials. |
static |
Specifies static files to be deployed as-is, thus without any processing by Hugo. |
We will now set up a new branch before we make any changes. It is a good software practice to set up at least one branch for development and testing, instead of working directly on the main branch. Hinode provides several predefined tests that verify if submitted changes in a Pull Request adhere to coding conventions and do not break the build.
Head over to the Source Control
section of VSCode and click on the button ...
to open the source control menu. Within the menu, navigate to Branch / Create Branch...
. Provide develop
as branch name and confirm with
enter
. The blue status bar on the bottom of VSCode will now display develop
as selected branch. A repository usually contains a main
branch that maintains the production code, and one or more development branches. Complex projects with multiple contributors may have multiple active (feature) branches and even nested branches.
Now let us replace the introduction of the featured section of our homepage. Replace the main content in content/_index.md
(below the last ---
marker) with the following.
This is my first site created with Hinode.
When done, head over to the address http://localhost:1313/
in your web browser to validate the result of the changes.
Our initial page is still rather empty. We will now create a new post and modify the existing about section. Still within the develop
branch, create a new folder content/posts
. This is a so-called root section and corresponds with the path /posts
of your published site. Next, create a new file in content/posts/first-post.md
. Add the following content:
---
title: This is my first post
date: 2023-08-15
thumbnail:
url: /img/sunrise.jpg
author: Harris Vo
authorURL: https://unsplash.com/@hoanvokim
origin: https://unsplash.com/photos/ZX6BPboJrYk
originName: Unsplash
---
This is my first site created with Hinode. It includes a single blog post.
The content contains frontmatter, denoted by ---
markers, and main content. The frontmatter captures the metadata of the page, and usually includes at least a title and a date. The thumbnail
is a special variable introduced by Hinode that captures the metadata of our page thumbnail. The image itself is mounted from the main Hinode repository into the assets
folder upon build.
Check back to see the changes in your web browser. If you do not see the new post, you might have to restart the web server. Hit
CTRL-C
and rerun the npm run start
command. Your page should now look similar to the following screenshot:
Hinode defines severals tests to validate the code adheres to coding standards. Run the following command to run the tests locally. The test should confirm our code is safe to check in.
npm run lint
> @gethinode/template@0.11.0 lint
> npm-run-all lint:**
> @gethinode/template@0.11.0 lint:scripts
> eslint assets/js --no-error-on-unmatched-pattern
> @gethinode/template@0.11.0 lint:styles
> stylelint "assets/scss/**/*.{css,sass,scss,sss,less}" --allow-empty-input
> @gethinode/template@0.11.0 lint:markdown
> markdownlint-cli2 "*.md" "content/**/*.md"
markdownlint-cli2 v0.8.1 (markdownlint v0.29.0)
Finding: *.md content/**/*.md !node_modules !CHANGELOG.md
Linting: 3 file(s)
Summary: 0 error(s)
Head over to VSCode’s Source Control to view the pending changes. Click on the file _index.md
to open the code inspector. VSCode will then show the differences between the previous version and current version of the file. Content that has been replaced or removed is marked red, and content that has been added or modified is marked green. Verify the change and click on the +
button to stage the modification of the _index.md
file. Enter a descriptive commit message such as Modify about section
. When done, click on the blue Commit
button to commit the changes to the develop
branch.
Tip
By convention, a commit message should use the imperative mood and should be less than 150 characters in total. Review the blog from Initial Commit to see more best practices and guidelines to write good commit messages .
VSCode highlights two additional changes, one being our new post and the other a file called hugo_stats.json
. This latter file is used by the purger to avoid required styles are removed unintentionally. Check the guide about
optimizing the user experience for an elaborate deep-dive. Stage and commit these two changes too. Lastly, click on the blue button Publish Branch
to submit the branch and its content to GitHub. For an existing branch you would push the button Sync Changes
instead.
With your changes committed to the remote develop branch, you can now merge the changes with the main branch. Head over to your repository on GitHub to submit a Pull Request (PR). Click on the green button New pull request
within the menu Pull Requests
to do so. Enter a descriptive title for the PR, or confirm the default title suggested by GitHub. Click on the green button to submit the PR, which triggers GitHub to run several checks.
By default, Hinode runs a linting test and builds the web site with the latest stable (LTS
) versions of Node.js. The linting test is the same test that ran in the
previous step. The tests act as a sort of safeguard to prevent changes breaking the main repository. You can confirm the merge when all checks have passed successfully. You can then observe the commit message associated with the content
folder when you head back to the code of the main repository.
You have now successfully created your initial Hinode site with version control and automated updates. You can look into the guide to automate the dependency upgrades using GitHub actions. Review the hosting and deployment options to see various options on how to (automatically) publish your site to a hosting provider.
Refer to the installation instructions if you prefer to install Hinode as a regular Hugo theme. ↩︎
By default macOS synchronizes your ~/Documents
folder with iCloud. Unfortunately this interferes with npm and could lead to all kinds of synchronization issues. You can better select a folder that is not synchronized with iCloud and let git handle your version control. ↩︎