siteup
builds websites with html, md, css and js.
Look at examples and siteup
dependents for some examples how siteup
can work.
siteup
is sort of like "markup", which is related to "markdown", which inspired the project sitedown
to which siteup
is a spiritual offshot of. Point siteup
at a folder of page documents, and get a website.
npm install @siteup/cli
$ siteup --help
Usage: siteup [options]
Example: siteup --src website --dest public
--src, -s path to source directory (default: "src")
--dest, -d path to build destination directory (default: "public")
--watch, -w build and watch the src folder for additional changes
--help, -h show help
--version, -v show version information
siteup (v0.0.11)
siteup
builds a src
directory into a dest
directory (default: public
).
Siteup builds a website from "pages" in a src
directory, 1:1 into a dest
directory.
A src
directory tree might look something like this:
src % tree
.
βββ a-page
β βββ README.md
β βββ client.js
β βββ libs
β β βββ a-lib.js
β βββ nested-page
β β βββ client.js
β β βββ page.js
β β βββ style.css
β βββ page.js
β βββ style.css
βββ client.js
βββ conflict-page
β βββ README.md
β βββ page.html
β βββ page.js
βββ favicon-16x16.png
βββ global.client.js
βββ global.css
βββ global.vars.js
βββ html-page
β βββ client.js
β βββ page.html
β βββ page.vars.js
β βββ style.css
βββ md-page
β βββ README.md
β βββ client.js
β βββ loose-md-page.md
β βββ style.css
βββ md-two
β βββ README.md
βββ nav.js
βββ page.js
βββ root.layout.js
βββ some-css.css
βββ style.css
7 directories, 30 files
The above src directory would transform into something like this in the dest
dir:
.
βββ a-page
β βββ client.js
β βββ client.js.map
β βββ index.html
β βββ nested-page
β β βββ client.js
β β βββ client.js.map
β β βββ index.html
β β βββ style.css
β βββ style.css
βββ chunk-HC4Q5QIB.js
βββ chunk-HC4Q5QIB.js.map
βββ chunk-WZ7JV6GS.js
βββ chunk-WZ7JV6GS.js.map
βββ client.js
βββ client.js.map
βββ favicon-16x16.png
βββ global.client.js
βββ global.client.js.map
βββ global.css
βββ global.css.map
βββ html-page
β βββ client.js
β βββ client.js.map
β βββ index.html
β βββ style.css
βββ index.html
βββ md-page
β βββ client.js
β βββ client.js.map
β βββ index.html
β βββ loose-md-page.html
β βββ style.css
βββ md-two
β βββ index.html
βββ style.css
A folder of markdown, html and js documents in the src
directory gets transformed into html documents in the dest
directory, along with page scoped js and css bundles, as well as a global stylesheet and global js bundle.
There are a few important (and optional) global assets that live at the root of the src
directory:
The root layout is a js file that export default
an async function that implements an outer-wrapper html of the inner content from the page (children
) being rendered.
It is always passed the following variables:
scripts
: array of paths that should be included onto the page in a script tag src with typemodule
.styles
: array of paths that should be included onto the page in alink rel="stylesheet"
tag with the href pointing to the paths in the array.children
: A string of the inner content of the page, or whatever type your js page functions returns.
The default root.layout.js
is featured below, and is implemented with uhtml
, though it could just be done with a template literal.
All other variables set in the page being rendered and global.vars.js
are passed in as well.
Variables are primarily consumed in the page layout, and you can implement many features with this simple concept.
import { html, render } from 'uhtml-isomorphic'
export default async function RootLayout ({
title,
siteName,
scripts,
styles,
children
}) {
return render(String, html`
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>${siteName}${title ? ` | ${title}` : ''}</title>
<meta name="viewport" content="width=device-width, user-scalable=no" />
${scripts
? scripts.map(script => html`<script src="${script}" type='module'></script>`)
: null}
${styles
? styles.map(style => html`<link rel="stylesheet" href=${style} />`)
: null}
</head>
<body>
${typeof children === 'string' ? html([children]) : children /* Support both uhtml and string children. Optional. */}
</body>
</html>
`)
}
The global.vars.js
file should export default
a variables object or a (sync or async) function that returns a variable object.
The variables in this file are available to all pages, unless the page sets a variable with the same key, taking a higher precedence.
This is a script bundle that is included on every page. It provides an easy way to inject analytics, or other small scripts that every page should have. Try to minimize what you put in here.
This is a global stylesheet that every page will use. Any styles that need to be on every single page should live here.
Pages are a named folder inside of src
, with one of the following page files inside of it.
md
pages are commonmark markdown pages.html
pages are static, inner-html fragments that get inserted as-is into the page layout.js
pages are a js file that exports an async function that resolves into an inner-html fragment that is inherited into the page layout. It is the only page that can access variables during rendering.
A md
page looks like this:
src/page-name/README.md
or
src/page-name/loose-md.md
md
pages have two types: aREADME.md
in a folder, or a loosewhatever-name-you-want.md
file.md
pages can have yaml frontmatter, with variables that are accessible to the page layout when building.- Frontmatter variables have higher precedence over
page.vars.js
orglobal.vars.js
variables. - You can include html in markdown files, so long as you adhere to the allowable markdown syntax around html tags.
A html
page looks like this:
src/page-name/page.html
html
pages are namedpage.html
inside an associated page folder.html
pages are the simplest page type insiteup
. They let you build with raw html for when you don't want that page to have access to markdown features. Some pages are better off with just rawhtml
.
A js
page looks like this:
src/page-name/page.js
js
pages are files inside a page folder calledpage.js
.- a
js
page needs toexport default
a function (async or sync) that accepts a variables argument and returns a string of the inner html of the page, or any other type that your layout can accept. - A
js
page is the only page type that can render with page and global variables. - A
js
page can export avars
object or function (async or sync) that takes highest variable precedence when rendering the page. It works similarly to markdown frontmatter variables.
All pages can have a client.js
and a style.css
file inside of their associated folder.
These are uniquely built and loaded on their associated page.
The client.js
page bundles are bundle split with every other client side js entry-point.
The style.css
page is not de-duplicated or split with other style files.
Each page can also have a page.vars.js
file that exports a default
function that contains page specific variables.
All static assets in the src
directory are copied 1:1 to the public
directory.
siteup
bundles the best tools for every technology in the stack:
js
is bundled withesbuild
.css
is processed withpostcss
.md
is processed with markdown-it.- static files are processed with cpx2.
These tools are treated as implementation details, but they may be exposed more in the future. The idea is that they can be swapped out for better tools in the future if they don't make it.
siteup
works and has a rudimentary watch command, but hasn't been battle tested yet.
If you end up trying it out, please open any issues or ideas that you have, and feel free to share what you build.
Some noteable features are included below, see the roadmap for a more in depth view of whats planned.
-
md
pages -
js
pages -
html
pages -
client.js
page bundles -
style.css
page stylesheets -
page.vars.js
page variables -
loose-markdown-pages.md
- Static asset copying.
- CLI build command
- CLI watch command
- Ignore globbing
- Nested site dest
- Default layouts/styles with 0 config starting point
- More examples and ideas.
- Hardened error handling w/ tests
- ...See roadmap
MIT