9.0.3 • Public • Published


    Free and open static site generator, that reads your input files and outputs web pages. My blog as an example

    Feature Overview

    • Index page for all posts and categories
    • Client side, ultra fast search
    • 100% lighthouse score, WCAG 2.1 compliant
    • cleaner than 94 % of web pages tested on
    • Opengraph support
    • Responsive design
    • Dark mode ready
    • Support audio and video inside posts
    • Output files are minified
    • Post sources can be text markdown html and more
    • Post sources can be any valid URL or local file
    • Semi private posts with indexed: false
    • Translation ready
    • Works without JavaScript
    • Fast (250 files in less than 3 seconds) and cli based

    Pro version

    To support the project and have additional features consider the pro version. Open an issue or chat if interested. The pro version includes

    • Comment system
    • Partial Webmention support
    • Web hosting and domain setup, costs included
    • Help to set up and/or help to migrate from other CMS
    • 6 hours of custom feature development for the site or the engine
    • Issues have priority over free users' issues
    • Ability to update blog content via simple file upload and/or git

    Cost: 650€ per site a year

    How to use ?

    Set up

    1. Download NodeJS 16+

    Set up with the template

    1. Copy template and follow instructions in its readme

    Set up manually

    1. Create a new project (folder)
    2. Create a valid package.json file with npm init for example
    3. Run npm i blog-engine-sac (may require sudo and --unsafe-perm)
    4. add scripts inside package.json
      "scripts": {
        "sac": "node node_modules/blog-engine-sac/source/main.js inputFolder=."
    1. follow instructions below to create required files
    2. npm run sac
    3. to view the results use a static file server

    Create a new post

    Create a new file in the folder source/. Supported file types:

    • text (.txt)
    • markdown (.md)
    • html (.html)
    • yaml (.yaml)
    • json (.json)
    • ini (.ini)
    • toml (.toml)

    A markdown file is a normal text file with .md file extension. The name of the file is used as the name of the post.

    Simple post

    Create a file in source/. For example or my-post.txt.

    Post with metadata

    Create a simple post then create a meta file with the same base name. For example my-post.yaml. Meta files in the readme will be yaml, but they can be any format in the list:

    • yaml
    • json
    • ini
    • toml
    coverImage: "post.jpg"
    # set coverImage to false to disable it
    title: "I am about to write a title"
    description: "Description"
    lang: en
    author: "Author name or URL"
    ready: true
    indexed: true
    listed: true
    editLink: false
    standalone: false
    creationDate: 2018/02/15
    modifiedDate: 2035/02/19
      - cooking
      - sports
      - travel
    translations: []
    license: CC0-1.0
    # comments
    # commentsDisabled: false

    set ready to false to not process them at all


    set indexed to false, to have it in the blog, but the index.html will not have a link to it and search will not find it. The only way to open it would be to know the exact URL.


    set listed to false, to have it in the blog, but the index.html will not have a link to it. Unlisted posts can still be found with search or by knowing the URL. If indexed is false, then the listed option has no effect.


    tags is a list of categories that your post will appear in. Categories are pages that list only post of that category. For example if you have "travel" inside categories inside blog-engine-sac settings, and travel as a tag of the post, then the post will be listed on the travel category. tags that are not in the categories will create a semi hidden category : a link from post to that category but unlisted on the index page.


    Use it to mark posts as translations of another post. If we have the following files:

    • (in English)
    • Gé (in French)
    • (in German)

    Use the following meta file to link them:

    lang: en
      - lang: fr
        src: ./Gé
      - lang: de
        src: ./

    Each translation item may use any key value pair seen above (title, author, etc)


    Should be a url or false. If it is an url, an edit link will be created for that post


    If true the html output will not be decorated by the usual (header, footer, next, previous, etc)


    If true the comments are disabled


    This should reflect the canonical url for a post. If you are the author of your articles, set this to false. If you take an article from another blog and would like machines to know the original canonical url for the article, set this to the original article's url. By default the canonical url will be self, for local posts, and src for remote posts.

    External post

    Create a file that describes where to find the external post. For example js-style-guide.yaml . Including a post from the web: Add a yaml file in source/ with src set to the url.

    src: ''

    Another Example with this readme file:

    src: ''
    canonicalUrl: ''
    lang: en
    Content-Type: text/markdown

    site settings

    Create file blog-engine-sac.yaml with

    # put the final url of the website and uncomment
    # url:
    defaultLang: en
    defaultAuthor: AUTHOR
    mainTitle: Blog
    subTitle: Change title and subtitle in blog-engine-sac.yaml
    defaultLicense: CC-BY-NC-4.0
    htmlExtensionLinks: false
    indexInBaseIndexLink: false # index link becomes just /
      - tag: travel
        "fr": voyages
      - tag: dance
        "fr": danse

    Ideally defaultLicense is a SPDX identifier.

    defaultLang is a 2 letter shorthand for the language (ISO 639-1).

    htmlExtensionLinks: If true, links will have the ".html" extension. Default is false.

    Change the values as you see fit.


    categories are provided by the user as an array for the entire blog

    for example: travel, cuisine, sports

    Each category will have a dedicated index page that acts like the main index page but only lists post of that category. Posts will be in that category if they have a corresponding tag.

    about page

    Create file source/

    contact page

    Create file source/


    Create file source/extras/

    Edit Images

    Open folder images Replace the images with new ones but keep the exact filename to not break the links. (Images are linked from other files, not copied, the name of the files are used)

    Required images

    • images/home.jpg
    • images/post.jpg

    Custom css

    Add the following key-value pair in your site settings.

    customCss: custom.css

    Then create a folder named css. Inside create a file custom.css. Then copy inside custom.css the first 2 rules found inside blog-engine-sac.css. These are some css variables easy to edit as a starting point.

    user provided tags

    found in the meta file as an array

    auto generated tags (disabled)

    are gathered from the plain text of each post based on heuristics (rarity and uniqueness)


    tags is a set that combines user provided tags and auto generated tags and title. It is used for search function. They are also displayed after the post.

    What is mark down

    A text format. Learn it here

    About the code

    Don't remove, edit or add any other file unless you know exactly what you are doing!

    HTML files

    are generated. Do not edit directly


    Design starting point

    Start Bootstrap - Clean Blog is a stylish, responsive blog theme for Bootstrap created by Start Bootstrap. This theme features a blog homepage, about page, contact page, and an example post page along with a working PHP contact form.


    Copyright and License

    CC0 (Only for blog-engine-sac itself)


    npm i blog-engine-sac

    DownloadsWeekly Downloads






    Unpacked Size

    1.09 MB

    Total Files


    Last publish


    • grossacasacs