Yet another static site generator based on Next.js
Aki-SSG is a static site generator that transforms your markdown contents into a site based on Next.js, using Tailwind CSS as CSS Framework.
- Fork this project to your own repo.
- Clone it to your local space.
- Write your site information in
src/data/site-config.ts
. - Run
pnpm install
to install dependencies. - Write your articles and pages.
- Run
pnpm dev
to preview your site. - Run
pnpm build
to build site. - Upload files in
out/
directory to your web server. - Set rewrite rules for Nginx or other web server.
- Enjoy it!
You should add this to your virtual host configuration file.
(Only Nginx configuration example will be provided currently)
location / {
try_files $uri $uri.html $uri/ =404;
}
error_page 404 /404.html;
location = /404.html {
internal;
}
The site config will be stored in src/data/site-config.ts
. This file is fully typed so there will be type hints.
Available configuration:
import { createConfig } from "../utils/createConfig";
export const config: SiteConfig = createConfig({
author: {
name: "Test", // Author name, displayed on the footer and copyright.
email: "[email protected]", // Author email, used to get the gravatar displayed on the navigation bar.
},
blog: {
hostname: "example.com", // The domain of site.
title: "Aki-SSG", // The title of site.
description: "Yet another site generated by Aki-SSG", // The description of site, displayed on the header of site.
favicon: "/favicon.ico", // The site Favicon.
},
style: {
primary_color: "#6db0ec", // The primary color of site.
header_image: "https://blog-oss.allenyou.top/image/658ad4c208349.png", // The header image of site.
header_image: { // Or you can use this to set different images for light or dark mode.
default: "https://blog-oss.allenyou.top/image/658ad4c208349.png", // Light mode
dark: "https://blog-oss.allenyou.top/image/658ad4c208349.png", // Dark mode
},
},
comment: { // Comment configuration.
enabled: false, // Disable comment.
},
comment: { // Or set it to enable waline comment.
enabled: true,
waline_api: ""
},
optimize: { // Some optimization configuration.
gravatar_mirror: "https://gravatar.com/avatar/", // Gravatar mirror to use.
cdn_prefix: "", // Optional, the cdn url prefix of your static assets. (Refers to assetPrefix config in next.config.ts)
// If not set, static assets will be imported locally.
thumb_query: "", // Optional, the part appended to the thumb image url refered in the posts and pages.
// When the image is not fully loaded, the low resolution thumbnails will be displayed.
// If not set, none of thumb will be displayed.
}
};);
The pages and articles will be written in Aki-SSG Flavored Markdown and saved as .md
files. Some information can be described in the front matter part of file(the part quoted with ---
before the body of file, written in YAML format)
Pages should be saved as .md
files in src/data/pages/
directory. Each file corespond to a page.
The file should be like:
---
slug: example
title: "Example page"
enable_comment: false
allow_index: true
navigation_title: "Page"
navigation_index: 1
---
The content to be displayed on the page should be written in markdown here.
And attributes in the front matter should be like:
Attribute Name | Description |
---|---|
slug | Describes the URL of this page. For example, if it is set to example , then the URL of this page will be /example . |
title | Describes the title of this page. |
enable_comment(Optional) | A boolean value, describes whether comments will be enabled on this page. Default value is false . |
allow_index(Optional) | A boolean value, describes whether spiders be allowed to index this page in robots.txt . Default value is false . |
navigation_title(Optional) | Describes the link content direct to this page shown on the navigation bar. If is left blank, there will be no navigation link to this page. |
navigation_index(Optional) | An integer, describes the order in which it appears in the navigation bar(in ascending order). Default value is 0 . |
Articles should be saved as .md
files in src/data/posts/
directory. Each file corespond to an article.
The file should be like:
---
id: 1
title: "Hello, World!"
description: 这是一篇测试文章
modified_at: "2024-10-04"
---
The content of this article should be written in markdown here.
And attributes in the front matter should be like:
Attribute Name | Description |
---|---|
id | A unique integer, be used to identify this article. The URL of this article would be /posts/:id |
title | Describes the title of this article. |
modified_at | Describes the date and time of the last time this article be modified. |
description(Optional) | Describes the abstract description of this article. If is left blank, "没有描述" will be used by default. |
The friend links will be saved in src/data/friend-link.ts
. This file is fully typed so there will be type hints.
The file will be like:
export const friend_link_list: FriendLink[] = [
{
// The name of friend link
title: "Example Friend Link",
// The URL of friend link
url: "https://example.com",
// The description of friend link
description: "This is an example friend link.",
// The avatar image of friend link (Optional)
// If not set, a default avatar will be used by default.
avatar: "",
},
];
With unified
, Aki-SSG uses a extended markdown as richtext standard.
Despite standard markdown grammar, you can use syntaxes below to make your content more colorful!
Aki-SSG supports GitHub Flavored Alerts.
> [!NOTE]
> Highlights information that users should take into account, even when skimming.
> [!TIP]
> Optional information to help a user be more successful.
> [!IMPORTANT]
> Crucial information necessary for users to succeed.
> [!WARNING]
> Critical content demanding immediate user attention due to potential risks.
> [!CAUTION]
> Negative potential consequences of an action.
Aki-SSG Flavored Markdown supports grammars from GFM completely.
Aki-SSG uses MathJax to render LaTex expressions.
Use $ Expression $
to insert an inline expression.
Or use syntax below to insert a block expression.
$$
Expression
$$
Aki-SSG supports Generic directives/plugins syntax as extension. Here are available directives:
Use ::bilibili[bvid="" cid=""]
to embed the Bilibili video player.
Parameter | Description |
---|---|
bvid | The BV ID for the video to embed. |
cid(Optional) | The episode id for the video to embed. |
Use ::friend_links
to insert a friend link list.
The friend links will be loaded from src/data/friend-link.ts
Every chat should be wrapped by :::chat
and :::
.
Inside a chat, use ::chat_sender{name="Name" avatar="Avatar URL" self}
to define a chat participant.
Parameter | Description |
---|---|
name | The displayed name of participant. |
avatar(Optional) | The URL of avatar image displayed for participant. If not defined, a default avatar with the first character of the name of participant will be used. |
self(Optional) | If set, the message of this participant will be displayed on the right. |
If participants are defined repeatedly, the later definition will override the earlier definition.
Use ::chat_item[Text]{name="Name" avatar="Avatar URL" self}
to define a message in chat.
Parameter | Description |
---|---|
name | The displayed name of participant. If this participant has been defined by using ::chat_sender , the defined parameter will be |
avatar(Optional) | The URL of avatar image displayed for participant. If not defined, a default avatar with the first character of the name of participant will be used. |
self(Optional) | If set, the message of this participant will be displayed on the right. |
It should be noted that participants defined by ::chat_sender
has the highest priority. When conflict appears, parameters set ::chat_item
will be overrided.
The RSS Feed file will be saved in /feed.xml
.
The Sitemap file will be saved in /sitemap.xml
.
The robots.txt
file will be saved in /robots.txt
.
The design of this project is imitated from tcdw/koi. Thanks for @tcdw's work!