### Running domstack Examples Source: https://domstack.net/index Provides instructions on how to clone the domstack repository, install dependencies, navigate to an example directory, install its specific dependencies, and start the example project. ```shell $ git clone git@github.com:bcomnes/domstack.git $ cd domstack # install the top level deps $ npm i $ cd example:{example-name} # install the example deps $ npm i # start the example $ npm start ``` -------------------------------- ### Install DOMStack Static Package Source: https://domstack.net/index Installs the core DOMStack static package using npm. This command is the primary way to begin using DOMStack for building static websites and web applications. ```bash npm install @domstack/static ``` -------------------------------- ### Markdown Page Example Source: https://domstack.net/index An example of a Markdown page file (`.md`) in DOMStack. It includes YAML front-matter for metadata and variables, and uses Handlebars for dynamic content rendering. ```markdown --- title: A title for a markdown page favoriteColor: 'Blue' --- Just writing about web development. ## Favorite colors My favorite color is {{ vars.favoriteColor }}. ``` -------------------------------- ### HTML Page Example Source: https://domstack.net/index An example of an HTML page file (`.html`) in DOMStack. It demonstrates basic HTML structure and the use of Handlebars for rendering variables, which are typically defined in a `page.vars.js` file. ```html

Favorite frameworks

``` -------------------------------- ### JavaScript Page Example Source: https://domstack.net/index An example of a JavaScript page file in DOMStack. Similar to TypeScript, it exports a default function that accepts context including page variables and returns an HTML string. ```javascript export default function (context) { const { pageVars } = context; return `

Welcome, ${pageVars.userName}!

The current time is ${new Date().toLocaleTimeString()}.

`; } ``` -------------------------------- ### TypeScript Page Example Source: https://domstack.net/index An example of a TypeScript page file in DOMStack. It shows how to export a default function that receives variables and returns an HTML string, which is then inserted into the page layout. ```typescript import { PageContext } from "domstack"; export default function (context: PageContext) { const { pageVars } = context; return `

Hello, ${pageVars.name}!

Your favorite color is ${pageVars.favoriteColor}.

`; } ``` -------------------------------- ### domstack Project Structure Example Source: https://domstack.net/index Illustrates the typical directory structure within a domstack project's 'src' folder. It shows how different file types like README.md, client scripts (ts/js), stylesheets (css), HTML pages, and layout files are organized to define website pages and structure. ```shell src % tree . ├── md-page │ ├── README.md # directories with README.md in them turn into /md-page/index.html. │ ├── client.ts # Every page can define its own client.ts script that loads only with it. │ ├── style.css # Every page can define its own style.css style that loads only with it. │ ├── loose-md-page.md # loose markdown get built in place, but lacks some page features. │ └── nested-page # pages are built in place and can nest. │ ├── README.md # This page is accessed at /md-page/nested-page/. │ ├── style.css # nested pages are just pages, so they also can have a page scoped client and style. │ └── client.js # Anywhere JS loads, you can use .js or .ts ├── html-page │ ├── client.tsx # client bundles can also be written in .jsx/.tsx │ ├── page.html # Raw html pages are also supported. They support handlebars template blocks. │ ├── page.vars.ts # pages can define page variables in a page.vars.ts │ └── style.css ├── js-page │ └── page.js # A page can also just be a plain javascript function that returns content. They can also be type checked. ├── ts-page │ ├── client.ts # domstack provides type-stripping via Node.JS and esbuild │ ├── page.vars.ts # use tsc to run typechecking │ └── page.ts ├── feeds │ └── feeds.template.ts # Templates let you generate any file you want from variables and page data. ├── page-with-workers │ ├── client.ts │ └── page.ts │ ├── counter.worker.ts # Web workers use a .worker.{ts,js} naming convention and are auto-bundled │ └── analytics.worker.js ├── layouts # layouts can live anywhere. The inner content of your page is slotted into your layout. │ ├── blog.layout.ts # pages specify which layout they want by setting a `layout` page variable. │ ├── blog.layout.css # layouts can define an additional layout style. │ ├── blog.layout.client.ts # layouts can also define a layout client. │ ├── article.layout.ts # layouts can extend other layouts, since they are just functions. │ ├── javascript.layout.js # layouts can also be written in javascript │ └── root.layout.ts # the default layout is called "root" ├── globals # global assets can live anywhere. Here they are in a folder called globals. │ ├── global.client.ts # you can define a global client that loads on every page. │ ├── global.css # you can define a global css file that loads on every page. │ ├── global.vars.ts # site wide variables get defined in global.vars.ts │ ├── markdown-it.settings.ts # You can customize the markdown-it instance used to render markdown │ └── esbuild.settings.ts # You can even customize the build settings passed to esbuild ├── README.md # This is just a top level page built from a README.md file. ├── client.ts # the top level page can define a page scoped js client. ├── style.css # the top level page can define a page scoped css style. └── favicon-16x16.png # static assets can live anywhere. Anything other than JS, CSS and HTML get copied over automatically. ``` -------------------------------- ### PostVars Example: Generating Blog Post HTML Source: https://domstack.net/index Demonstrates an asynchronous `postVars` function that introspects pages to generate an HTML list of recent blog post titles and publish dates. This generated HTML can then be injected into markdown pages. ```typescript import { html } from 'htm/preact' import { render } from 'preact-render-to-string' import type { PostVarsFunction } from '@domstack/static' export const postVars: PostVarsFunction = async ({ pages }) => { const blogPosts = pages .filter(page => page.vars.layout === 'article') .sort((a, b) => new Date(b.vars.publishDate) - new Date(a.vars.publishDate)) .slice(0, 5) const blogpostsHtml = render(html``) return { blogPostsHtml: blogpostsHtml } } ``` -------------------------------- ### TypeScript Page with Preact and Htm Source: https://domstack.net/index An advanced example of a TypeScript page using Preact and htm for templating. It illustrates filtering pages based on directory structure and rendering dynamic lists with links, demonstrating component-based rendering. ```typescript import { html } from 'htm/preact' import { dirname, basename } from 'node:path' import type { PageFunction } from '@domstack/static' type BlogVars = { favoriteCake: string } export const vars = { favoriteCake: 'Chocolate Cloud Cake' } export default const blogIndex: PageFunction = async ({ vars: { favoriteCake }, pages }) => { const yearPages = pages.filter(page => dirname(page.pageInfo.path) === 'blog') return html`

I love ${favoriteCake}!!

` } ``` -------------------------------- ### DOMStack Template Function API Source: https://domstack.net/index Documents the DOMStack TemplateFunction API, which allows generating files dynamically. It covers simple string templates and object templates with content and output name overrides, including type definitions and usage examples. ```APIDOC TemplateFunction API: Template files are TS/JS files that default export a sync or async function. 1. Simple String Template: - Function returns a string. - Output filename is derived from the template filename (e.g., `name-of-template.txt.template.ts` becomes `name-of-template.txt`). - Example: ```typescript import type { TemplateFunction } from '@domstack/static' interface TemplateVars { foo: string; testVar: string; } export default const simpleTemplate: TemplateFunction = async ({ vars: { foo, testVar } }) => { return `Hello world\n\nThis is just a file with access to global vars: ${foo}` } ``` 2. Object Template: - Function returns an object with `content` (string) and `outputName` (string) properties. - `outputName` allows overriding the default output filename. - Example: ```typescript import type { TemplateFunction } from '@domstack/static' interface TemplateVars { foo: string; } export default async ({ vars: { foo } }) => ({ content: `Hello world\n\nThis is just a file with access to global vars: ${foo}`, outputName: './single-object-override.txt' }) ``` Parameters for TemplateFunction: - `vars`: An object containing variables available at build time, including global site variables. - `context`: Additional context information (details not provided in source). ``` -------------------------------- ### Local Release Process with npm Source: https://domstack.net/CONTRIBUTING Manual steps for releasing the project locally if the automated GitHub Actions process is not used or fails. Ensures a clean workspace before versioning and publishing. ```APIDOC Local npm Release Steps: Description: Manual procedure for releasing the project locally. Prerequisites: - Clean working git workspace. Steps: 1. Run `npm version {patch,minor,major}`: - Updates the version number in package.json. - Generates the changelog. - Commits the version change and creates a tag. 2. Run `npm publish`: - Pushes local git branch and tags to the default remote. - Performs a gh-release. - Creates an npm publication. Commands: - npm version - version_type: 'patch', 'minor', or 'major'. - npm publish Related Tools: - gh-release: Used for creating GitHub releases. ``` -------------------------------- ### DOMStack CLI Usage Source: https://domstack.net/index Demonstrates the command-line interface for DOMStack, including common options for source and destination directories, watch mode, and ejecting default configurations. It outlines the primary commands and their functionalities. ```bash $ domstack --help Usage: domstack [options] Example: domstack --src website --dest public --src, -s path to source directory (default: "src") --dest, -d path to build destination directory (default: "public") --ignore, -i comma separated gitignore style ignore string --drafts Build draft pages with the `.draft.{md,js,ts,html}` page suffix. --eject, -e eject the DOMStack default layout, style and client into the src flag directory --watch, -w build, watch and serve the site build --watch-only watch and build the src folder without serving --copy path to directories to copy into dist; can be used multiple times --help, -h show help --version, -v show version information domstack (v11.0.0) ``` -------------------------------- ### Domstack Net buildPages() Process Flow Source: https://domstack.net/index Visualizes the parallel execution of the buildPages() function, showing the Resolve Once phase, the Parallel Page Queue with concurrency limits, and the individual tasks for Markdown, HTML, and JavaScript pages, including steps like reading files, extracting frontmatter, variable resolution, and rendering. ```text ┌──────────────────┐ │ buildPages() │ └────────┬─────────┘ │ ┌────────▼─────────┐ │ Resolve Once: │ │ • Global vars │ │ • All layouts │ └────────┬─────────┘ │ ┌────────────▼───────────────┐ │ Parallel Page Queue │ │(Concurrency: min(CPUs, 24))│ └────────────┬───────────────┘ │ ┌────────────────────┼────────────────────┐ │ │ │ ▼ ▼ ▼ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │ MD Page Task │ │ HTML Page Task │ │ JS Page Task │ ├─────────────────┤ ├─────────────────┤ ├─────────────────┤ │ ┌─────────────┐ │ │ ┌─────────────┐ │ │ ┌─────────────┐ │ │ │1. Read .md │ │ │ │1. Read .html│ │ │ │1. Import .js│ │ │ │ file │ │ │ │ file │ │ │ │ module │ │ │ └──────┬──────┘ │ │ └──────┬──────┘ │ │ └──────┬──────┘ │ │ ▼ │ │ ▼ │ │ ▼ │ │ ┌─────────────┐ │ │ ┌─────────────┐ │ │ ┌─────────────┐ │ │ │2. Extract │ │ │ │2. Variable │ │ │ │2. Variable │ │ │ │ frontmatter │ │ │ │ Resolution │ │ │ │ Resolution │ │ │ └──────┬──────┘ │ │ └──────┬──────┘ │ │ └──────┬──────┘ │ │ ▼ │ │ ▼ │ │ ▼ │ │ ┌─────────────┐ │ │ ┌─────────────┐ │ │ ┌─────────────┐ │ │ │ Frontmatter │ │ │ │page.vars.js │ │ │ │ Exported │ │ │ │ vars │ │ │ │ │ │ │ │ vars │ │ │ └──────┬──────┘ │ │ └──────┬──────┘ │ │ └──────┬──────┘ │ │ ▼ │ │ ▼ │ │ ▼ │ │ ┌─────────────┐ │ │ ┌─────────────┐ │ │ ┌─────────────┐ │ │ │page.vars.js │ │ │ │ postVars │ │ │ │page.vars.js │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └──────┬──────┘ │ │ └──────┬──────┘ │ │ └──────┬──────┘ │ │ ▼ │ │ ▼ │ │ ▼ │ │ ┌─────────────┐ │ │ ┌─────────────┐ │ │ ┌─────────────┐ │ │ │ postVars │ │ │ │3. Handlebars│ │ │ │ postVars │ │ │ │ │ │ │ │ (if enabled)│ │ │ │ │ │ │ └──────┬──────┘ │ │ └──────┬──────┘ │ │ └──────┬──────┘ │ │ ▼ │ │ ▼ │ │ ▼ │ │ ┌─────────────┐ │ │ ┌─────────────┐ │ │ ┌─────────────┐ │ │ │3. Render MD │ │ │ │4. Render │ │ │ │3. Execute │ │ │ │ to HTML │ │ │ │ with layout│ │ │ │ page func │ │ │ └──────┬──────┘ │ │ └──────┬──────┘ │ │ └──────┬──────┘ │ │ ▼ │ │ ▼ │ │ ▼ │ │ ┌─────────────┐ │ │ ┌─────────────┐ │ │ ┌─────────────┐ │ │ │4. Extract │ │ │ │5. Write HTML│ │ │ │4. Render │ │ │ │ title (h1) │ │ │ │ │ │ │ │ with layout│ │ │ └──────┬──────┘ │ │ └─────────────┘ │ │ └──────┬──────┘ │ │ ▼ │ │ │ │ ▼ │ │ ┌─────────────┐ │ │ │ │ ┌─────────────┐ │ │ │5. Render │ │ │ │ │ │5. Write HTML│ │ │ │ with layout│ │ │ │ │ │ │ │ │ └──────┬──────┘ │ │ │ │ └─────────────┘ │ │ ▼ │ │ │ │ │ │ ┌─────────────┐ │ │ │ │ │ │ │6. Write HTML│ │ │ │ │ │ │ └─────────────┘ │ │ │ │ │ └─────────────────┘ └─────────────────┘ └─────────────────┘ │ │ │ └──────────────────────┼──────────────────────┘ │ ▼ ┌──────────────────┐ │ Complete when │ │ all pages done │ └──────────────────┘ ``` -------------------------------- ### Client-Side JavaScript Bundle Source: https://domstack.net/index Illustrates creating a client-side JavaScript bundle (`client.js` or `client.ts`) for a specific page. It shows importing external libraries and local helper functions, and using top-level await for asynchronous operations. ```javascript /* /some-page/client.ts */ import { funnyLibrary } from 'funny-library' import { someHelper } from '../helpers/foo.js' await someHelper() await funnyLibrary() ``` -------------------------------- ### Web Worker Initialization Source: https://domstack.net/index This JavaScript code demonstrates how to fetch worker paths from `workers.json` and initialize a new Web Worker. It uses `import.meta.url` for module resolution and includes basic message posting and handling. ```javascript async function initializeWorkers() { const response = await fetch('./workers.json'); const workersData = await response.json(); // Initialize workers with the correct hashed filenames const counterWorker = new Worker( new URL(`./${workersData.counter}`, import.meta.url), { type: 'module' } ); // Use the worker counterWorker.postMessage({ action: 'increment' }); counterWorker.onmessage = (e) => { console.log(e.data); }; return counterWorker; } const worker = await initializeWorkers(); ``` -------------------------------- ### Nested Blog Layout with TypeScript and Preact Source: https://domstack.net/index Demonstrates creating a nested layout (`blog.layout.ts`) that extends a root layout. It uses Preact for rendering and defines specific variables for blog posts, showing how to compose layouts by passing children and arguments. ```typescript import defaultRootLayout from './root.layout.js' import { html } from 'htm/preact' import { render } from 'preact-render-to-string' import type { LayoutFunction } from '@domstack/static' // Import the type from root layout import type { RootLayoutVars } from './root.layout' // Extend the RootLayoutVars with blog-specific properties interface BlogLayoutVars extends RootLayoutVars { authorImgUrl?: string; authorImgAlt?: string; authorName?: string; authorUrl?: string; publishDate?: string; updatedDate?: string; } const blogLayout: LayoutFunction = (layoutVars) => { const { children: innerChildren, ...rest } = layoutVars const vars = layoutVars.vars const children = render(html`

${vars.title}

${vars.publishDate ? html` ` : null } ${vars.updatedDate ? html`` : null }
${typeof innerChildren === 'string' ? html`
` : innerChildren }
`) const rootArgs = { ...rest, children } return defaultRootLayout(rootArgs) } export default blogLayout ``` -------------------------------- ### Automated Release via GitHub Actions Source: https://domstack.net/CONTRIBUTING Initiates the release process by triggering the 'npm bump' action in GitHub Actions. This action handles changelog generation, GitHub release creation, and npm package publishing. ```APIDOC GitHub Actions - npm bump: Description: Automates release workflow including version bumping, changelog generation, and publishing. Trigger: Manual trigger via GitHub Actions tab. Parameters: - semantic_version_bump: (string) Required. Specifies the type of version bump (e.g., 'patch', 'minor', 'major'). Process: 1. Navigate to the project's GitHub Actions tab. 2. Select the 'npm bump' workflow. 3. Trigger the workflow, providing the required semantic version bump. Outcome: - Updates package.json version. - Generates changelog. - Creates a GitHub release. - Publishes the package to npm. Reference: [bret.io/projects/package-automation](https://bret.io/projects/package-automation/) ``` -------------------------------- ### Page CSS with Imports Source: https://domstack.net/index Shows how to define local page styles using a `style.css` file. It demonstrates using CSS `@import` statements to include styles from npm modules or local files, and defines scoped styles. ```css /* /some-page/style.css */ @import "some-npm-module/style.css"; @import "../common-styles/button.css"; .some-page-class { color: blue; & .button { color: purple; } } ``` -------------------------------- ### Page Layout Referencing Source: https://domstack.net/index Pages can specify which layout to use by setting the `layout` variable in their frontmatter. If no layout is specified, the page defaults to the `root` layout. Referencing a non-existent layout will cause a build error. ```yaml --- layout: 'article' title: 'My Article Title' --- Thanks for reading my article ``` -------------------------------- ### Handlebars Placeholder for PostVars Output Source: https://domstack.net/index Shows how to use a Handlebars placeholder to insert the `blogPostsHtml` variable, generated by the `postVars` function, into a markdown file. ```html ## [Blog](./blog/) {{{ vars.blogPostsHtml }}} ``` -------------------------------- ### Draft Page File Naming Source: https://domstack.net/index Pages can be designated as drafts by adding a `.draft` extension to their file names (e.g., `.draft.md`, `.draft.html`, `.draft.ts`, `.draft.js`). Draft pages are excluded from builds by default but can be included using the `--drafts` flag. ```text page.draft.md page.draft.html page.draft.ts page.draft.js ``` -------------------------------- ### Recommended tsconfig.json for Domstack Source: https://domstack.net/index Provides a recommended `tsconfig.json` configuration for use with Domstack, extending `@voxpelli/tsconfig` for type checking and enabling specific compiler options for type stripping and module handling. ```json { "extends": "@voxpelli/tsconfig/node20.json", "compilerOptions": { "skipLibCheck": true, "erasableSyntaxOnly": true, "allowImportingTsExtensions": true, "rewriteRelativeImportExtensions": true, "verbatimModuleSyntax": true }, "include": [ "**/*", ], "exclude": [ "**/*.js", "node_modules", "coverage", ".github" ] } ``` -------------------------------- ### Configure markdown-it Plugins and Settings Source: https://domstack.net/index Enables customization of the markdown-it parser by exporting a default async function. This function accepts the markdown-it instance and allows adding plugins or modifying parser configurations. ```typescript import markdownItContainer from 'markdown-it-container' import markdownItPlantuml from 'markdown-it-plantuml' import type { MarkdownIt } from 'markdown-it' export default const markdownItSettingsOverride = async (md: MarkdownIt) => { // Add custom plugins md.use(markdownItContainer, 'spoiler', { validate: (params: string) => { return params.trim().match(/^spoiler\s+(.*)$/) !== null }, render: (tokens: any[], idx: number) => { const m = tokens[idx].info.trim().match(/^spoiler\s+(.*)$/) if (tokens[idx].nesting === 1) { return '
' + md.utils.escapeHtml(m[1]) + '\n' } else { return '
\n' } } }) md.use(markdownItPlantuml) return md } ``` ```typescript import markdownIt, { MarkdownIt } from 'markdown-it' import myCustomPlugin from './my-custom-plugin' export default const markdownItSettingsOverride = async (md: MarkdownIt) => { // Create a new instance with different settings const newMd = markdownIt({ html: false, // Disable HTML tags in source breaks: true, // Convert \n to
linkify: false, // Disable auto-linking }) // Add only the plugins you want newMd.use(myCustomPlugin) return newMd } markdownItSettingsOverride ``` -------------------------------- ### HTML Page Structure Source: https://domstack.net/index Defines the file system structure for HTML pages in DOMStack. HTML pages must be named `page.html` within their respective page directories. ```html src/page-name/page.html ``` -------------------------------- ### Importing Nested Layout Styles Source: https://domstack.net/index Demonstrates how to import CSS styles from a parent layout into a child layout to ensure all styles are included in the final build. ```css @import "./root.layout.css"; ``` -------------------------------- ### Layout-Specific Client-Side Scripting Source: https://domstack.net/index Demonstrates how to include client-side JavaScript or TypeScript logic for a layout by creating a `.layout.client.ts` or `.layout.client.js` file. These bundles are processed by esbuild and executed on every page that utilizes the associated layout. ```typescript /* /layouts/article.layout.client.ts */ console.log('I run on every page rendered with the \'article\' layout') /* This layout client is included in every page rendered with the 'article' layout */ ``` -------------------------------- ### Importing Nested Layout Client Scripts Source: https://domstack.net/index Shows how to import client-side JavaScript from a parent layout into a child layout to ensure all client logic is bundled together. ```typescript import './root.layout.client.ts' ``` -------------------------------- ### Layout-Specific CSS Styling Source: https://domstack.net/index Illustrates how to associate CSS styles with a specific layout file by creating a companion `.layout.css` file. These styles are bundled by esbuild and automatically applied to all pages rendered using that particular layout. ```css /* /layouts/article.layout.css */ .layout-specific-class { color: blue; & .button { color: purple; } } /* This layout style is included in every page rendered with the 'article' layout */ ``` -------------------------------- ### Basic TypeScript Page Structure Source: https://domstack.net/index Demonstrates the fundamental structure of a TypeScript page in Domstack. It shows how to export variables and a default async function that returns HTML content, accepting page variables. ```typescript import type { PageFunction } from '@domstack/static' export const vars = { favoriteCookie: 'Chocolate Chip with Sea Salt' } export default const page: PageFunction = async ({ vars }) => { return /* html */`

This is just some html.

My favorite cookie: ${vars.favoriteCookie}

` } ``` -------------------------------- ### DOMStack Copy Directories Flag Source: https://domstack.net/index Explains the --copy flag, which allows specifying directories outside the 'dest' folder to be copied verbatim into the destination. This is useful for including legacy or unprocessed static content. ```bash domstack --copy ./oldsite ``` -------------------------------- ### Page Variable Files Source: https://domstack.net/index Demonstrates creating page-specific variables using `page.vars.ts` or `page.vars.js`. It shows exporting variables as an object or as a synchronous or asynchronous function, detailing their precedence in the Domstack variable hierarchy. ```javascript // export an object export default { my: 'vars' } // OR export a default function export default () => { return { my: 'vars' } } // OR export a default async function export default async () => { return { my: 'vars' } } ``` -------------------------------- ### Web Worker File Structure Source: https://domstack.net/index Web workers for a page are created by adding a `${name}.worker.ts` or `${name}.worker.js` file to the same directory as the page. DOMStack bundles these workers, and their entry points are managed via a `workers.json` file. ```text page-directory/ ├── page.js ├── client.js ├── counter.worker.js # Worker with counter functionality └── data.worker.js # Worker for data processing ``` -------------------------------- ### RSS and JSON Feed Generation (TypeScript) Source: https://domstack.net/index An AsyncIterator template demonstrating how to generate RSS and JSON feeds from website pages. It filters pages by layout, sorts them by publish date, and uses external libraries for conversion. ```typescript import pMap from 'p-map' import jsonfeedToAtom from 'jsonfeed-to-atom' import type { TemplateAsyncIterator } from '@domstack/static' interface TemplateVars { title: string; layout: string; siteName: string; homePageUrl: string; authorName: string; authorUrl: string; authorImgUrl?: string; siteDescription: string; language: string; } export default const feedsTemplate: TemplateAsyncIterator = async function * ({ vars: { siteName, siteDescription, homePageUrl, language = 'en-us', authorName, authorUrl, authorImgUrl, }, pages }) { const blogPosts = pages .filter(page => page.pageInfo.path.startsWith('blog/') && page.vars['layout'] === 'blog') .sort((a, b) => new Date(b.vars.publishDate) - new Date(a.vars.publishDate)) .slice(0, 10) const jsonFeed = { version: 'https://jsonfeed.org/version/1', title: siteName, home_page_url: homePageUrl, feed_url: `${homePageUrl}/feed.json`, description: siteDescription, author: { name: authorName, url: authorUrl, avatar: authorImgUrl }, items: await pMap(blogPosts, async (page) => { return { date_published: page.vars['publishDate'], title: page.vars['title'], url: `${homePageUrl}/${page.pageInfo.path}/`, id: `${homePageUrl}/${page.pageInfo.path}/#${page.vars['publishDate']}`, content_html: await page.renderInnerPage({ pages }) } }, { concurrency: 4 }) } yield { content: JSON.stringify(jsonFeed, null, ' '), outputName: './feeds/feed.json' } yield { content: jsonfeedToAtom(jsonFeed), outputName: './feeds/feed.xml' } } ``` -------------------------------- ### Customize esbuild Settings Source: https://domstack.net/index Allows modification of esbuild build settings by exporting a default async function. This function receives the esbuild settings object and returns a modified version. Use with caution as it can break the build. ```typescript import { polyfillNode } from 'esbuild-plugin-polyfill-node' import type { BuildOptions } from '@domstack/static' export default const esbuildSettingsOverride = async (esbuildSettings: BuildOptions): Promise => { esbuildSettings.plugins = [polyfillNode()] return esbuildSettings } ``` -------------------------------- ### DOMStack Eject Command Source: https://domstack.net/index Details the effects of the --eject flag, which extracts DOMStack's default layout, global CSS, and client-side JavaScript into the user's source directory for customization. It also lists the dependencies added to package.json. ```bash domstack --eject ``` ```json Dependencies added: * mine.css * preact * htm * preact-render-to-string * highlight.js ``` -------------------------------- ### Markdown Page Structure Source: https://domstack.net/index Describes the file system structure for Markdown pages within DOMStack. Markdown files can be named README.md for index pages or any other name for specific pages. ```markdown src/page-name/README.md # or src/page-name/loose-md.md ``` -------------------------------- ### Default Root Layout Implementation with Preact and HTM Source: https://domstack.net/index This TypeScript code defines the default root layout for a Domstack project. It uses Preact and HTM to construct the main HTML structure, including head and body elements, and dynamically injects scripts and styles. The layout function receives various data objects to customize the page rendering. ```typescript import { html } from 'htm/preact' import { render } from 'preact-render-to-string' import type { LayoutFunction } from '@domstack/static' type RootLayoutVars = { title: string, siteName: string, defaultStyle: boolean, basePath?: string } export default const defaultRootLayout: LayoutFunction = ({ vars: { title, siteName = 'Domstack', basePath, /* defaultStyle = true Set this to false in global or page vars to disable the default style in the default layout */ }, scripts, styles, children, pages, page, }) => { return /* html */` ${render(html` ${title ? `${title}` : ''}${title && siteName ? ' | ' : ''}${siteName} ${scripts ? scripts.map(script => html`