create-microsite v0.2.0
microsite is a fast, opinionated static-site generator (SSG) that outputs extremely minimal clientside code using automatic partial hydration. Pages are written with Preact, Typescript, and CSS Modules and compiled with esbuild.
npm init microsite <project>Microsite is output as ESM, so it needs to run in a Node environment which supports it (node@12.19.0).
Ensure that your project includes
"type": "module"inpackage.json, which will allow you to use ESM in your project'snodescripts.
Automatic Partial Hydration (APH)
The most exciting feature of Microsite is automatic partial hydration. Current solutions send the entire component tree, which has already been rendered server-side, to the client for hydration.
Microsite, on the other hand, uses a hint from the author (the withHydrate HOC) to strip away any unnecessary code and ship highly optimized code to the client.
import { withHydrate } from "microsite/hydrate";
const Counter = () => {
const [count, setCount] = useState(0);
return (
<>
<button onClick={() => setCount((v) => v - 1)}>-</button>
<span>{count}</span>
<button onClick={() => setCount((v) => v + 1)}>+</button>
</>
);
};
export default withHydrate(Counter, { method: "idle" });There are a few rules to keep in mind when leveraging APH:
Hydrated components cannot contain any other hydrated component, as hydration is controlled by the top-level component.
Hydrated components should be placed as deep as possible in your app's tree for the most efficient bundles.
Hydrated components can't accept rich children, because it's non-trivial to serialize them, though I have some ideas to address this. For now, strings and numbers as children are fine.
withHydrate Options
method
As a developer, you know exactly how your site is structured, so Microsite allows you to tweak how hydration occurs, optimizing for your specific use cases.
idle(default) hydrates the component as soon as possible, when the browser executesrequestIdleCallbackcode.visiblehydrates the component as soon as it enters the viewport, viaIntersectionObserver.interactionhydrates the component as soon as the user interacts with it (viafocusorpointerenterevents.)
Pages
Microsite uses the file-system to generate your output, meaning each component in src/pages outputs a corresponding HTML file.
Page templates are written as .tsx files with Preact.
Styles
Styles are written using CSS Modules. src/global.css is, as you guessed, a global CSS file injected on every page.
Per-page/per-component styles are also inject on the correct pages. They are modules and must be named *.module.css.
Project structure
Microsite cares about the structure of your project. It should look like this:
project/
├── src/
│ ├── global.css
│ ├── global.ts // shipped entirely to client, if present
│ ├── pages/ // fs-based routing like Next.js
│ │ └── index.tsx
│ └── public/ // copied to dist/
└── tsconfig.jsonAcknowledgments
- Markus Oberlehner,
vue-lazy-hydration - Markus Oberlehner, Building Partially Hydrated, Progressively Enhanced Static Websites with Isomorphic Preact and Eleventy
- Lukas Bombach, The case of partial hydration (with Next and Preact)
- Jason Miller and Addy Osmani, Rendering on the Web
- Poimandres,
valtiofor inspiringmicrosite/global
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago