https://github.com/coxmi/toast
A tiny static site generator that doesn't specify a framework. Bring your own compilation.
https://github.com/coxmi/toast
ssg static-site-generator webpack
Last synced: 6 months ago
JSON representation
A tiny static site generator that doesn't specify a framework. Bring your own compilation.
- Host: GitHub
- URL: https://github.com/coxmi/toast
- Owner: coxmi
- License: cc0-1.0
- Created: 2021-07-02T09:48:42.000Z (about 5 years ago)
- Default Branch: main
- Last Pushed: 2022-05-22T10:41:49.000Z (about 4 years ago)
- Last Synced: 2025-10-06T03:16:40.366Z (9 months ago)
- Topics: ssg, static-site-generator, webpack
- Language: TypeScript
- Homepage: https://npmjs.com/toast-static
- Size: 3.35 MB
- Stars: 1
- Watchers: 1
- Forks: 0
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
Please note: This library is a work in progress!
# toast
### A really tiny static site generator plugin for webpack
Turn external data sources into a static site without specifying your development environment. Transpile, generate, or concatenate your templates however you want, toast is just a step in your build process. You’re not tied to using today’s framework of choice, so you can use es6 template literals for your `sitemap.xml`, `jsx` for your ``, or `ejs` for your ``.
- bring your own transpilation (using [webpack](https://webpack.js.org/))
- just return a `string` in your template render function
- no magic filenames or frontmatter: set urls in your template files
- fetch data from anywhere: just export a `Promise` or `async` function
## Usage
```js
// use javascript to get your content from anywhere you like
export const content = { title: 'Hello, World!' }
// set the url of your page
export const url = '/'
// render your template
export const html = (content, meta) =>
`
${content.title}
`
```
## Setup
### Install
```bash
npm install toast-static --save-dev
```
### Configure webpack
Add the plugin to your `webpack.config.js`:
```js
const { WebpackToastPlugin } = require('toast-static/webpack')
module.exports = {
output: {
path: outputDir,
filename: '[name].js',
},
plugins: [
new WebpackToastPlugin({
templates: './templates/**.js' // glob, path, or array
})
]
}
```
## Templates
A template is just a simple js file with some exports.
`pages/latest.js`:
```js
// grab your data (optional)
export const content = fetch('https://xkcd.com/info.0.json').then((res) => res.json())
// set your output url (starting with a forward-slash)
export const url = (content, meta) => '/latest/'
// render your html (or css, json, xml, rss, svg, or any other string-based format)
export const html = (content, meta) =>
`
${content.title}
`
```
### Collections
Export an iterable to `collection`, and a page will be generated for each item.
`pages/drinks.js`:
```js
export const collection = fetch('https://thecocktaildb.com/api/json/v1/1/filter.php?i=Mango').then((res) => res.json())
export const url = (content, meta) => `/drinks/${content.idDrink}/`
export const html = (content, meta) =>
`
${content.strDrink}
`
```
### Pagination
To split up a collection into pages, just export a number to `perPage`.
`pages/blog.js`:
```js
export const collection = [
{ url: 'hello-world' },
{ url: 'how-i-only-used-1-million-dependencies-to-build-my-new-blog' },
{ url: 'who-needs-reactjs-anyway' },
{ url: 'framework-fatigue-in-2041' },
{ url: 'ai-generated-webpack-config' },
{ url: 'the-singularity-came-from-css-houdini' }
]
// split posts into groups of five
export const perPage = 5
// set url to "/posts" for first page, and "/posts/2" for others
export const url = (content, meta) => {
return (meta.currentPage === 1)
? `/posts/`
: `/posts/${meta.currentPage}/`
}
export const html = (content, meta) =>
`
Page ${meta.currentPage} of ${meta.lastPage}
- ${post.url} `
${content.map(post =>
`
).join('')}
`
```
# Template exports
| Name | Purpose | Valid signatures
| :--- | :--- | :--- |
| `html` | Outputs the page content
Function is passed `content` and `meta` arguments to help render the page | `async (content, meta) => string`
`string` |
| `url` | Sets the page url
Must begin with a `/`. | `async (content, meta) => string`
`string` |
| `content` | (optional) Use to fetch the data from anywhere
(result is passed to `html` function) | `async () => any`
`any` |
| `collection` | (optional) Fetch a set of items
Each item generates a page | `async () => []`
`[]` |
| `perPage` | (optional) split a `collection` into chunks for pagination | `number` |
### `html` and `url` function arguments
#### `content`
`content` is the value exported by your `content` or `collection` function in the template, whichever takes precedence.
#### `meta`
`meta` is an object with the following properties:
- `url`: the pretty url returned from your `url` function (e.g. `/`)
- `output`: the path to the file created (e.g. `/index.html`)
- `outputDir`: absolute path to the output directory
- `root`: relative path from the current page to the document root
- `relative(pathFromRoot)`: returns the relative path to an asset from the current page
- `currentPage`: the current page in a collection
- `firstPage`: the first page in a collection
- `lastPage`: the last page in a collection
- `previousPage`: the previous page in a collection
- `nextPage`: the next page in a collection
- `firstIndexOnPage`: the first item on the current page (counting from 0)
- `lastIndexOnPage`: the last item on the current page (counting from 0)
- `firstItemOnPage`: the first item on the current page (counting from 1)
- `lastItemOnPage`: the first item on the current page (counting from 1)
### Page context (accessing `content` and `meta`)
Calling `context()` within your template functions gives you access to the `content` and `meta` variables, without having to pass them through each function call (including within async components, or deep within the render tree)
```js
import { context } from 'toast-static'
const { content, meta } = context()
```
# Contributing
Contributions welcome!