diff --git a/README.md b/README.md
index 60b9b1c..1aa6b2a 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
# vite-plugin-minissg
-[Minissg] (pronounce it as "missing" 😄) is a minimum-sized,
+Minissg (pronounce it as "missing" 😄) is a minimum-sized,
configurable, and zero-JS static site generator, provided as a Vite
plugin.
@@ -12,1405 +12,10 @@ framework, so that it does not hide anything in JS and Vite from the
users.
With Minissg, any decision and convention for static site generation
are up to you; for example, you can write your static webpages with
-any of your favorite technologies including [React], [Preact],
-[Solid], [Svelte], [Vue], [Markdown], [MDX], and even any combination
-of them, in exchange of a little effort to write some JS code and some
-configurations in `vite.config.js`.
+any combination of your favorite JS technologies in exchange of a
+little effort to write some JS code and some configurations in
+`vite.config.js`.
-The core part of Minissg consists only about 1,100 lines of code in
-TypeScript (actually, this README has more lines than Minissg).
-This small codebase allows you to easily understand what Minissg does
-and does not.
-Including this point, Minissg aims to be not an opinionated framework,
-but a _transparent atmosphere_, which does not lead you to anything
-but maximum freedom of static site programming.
+See [packages/vite-plugin-minissg/README.md] for details.
-## Getting Started
-
-Template projects using Minissg with Preact, React, Solid, Svelte, Vue,
-and MDX are available in this repository.
-See [template directory](./template/) for the full list of templates.
-You can start your project with one of these templates by downloading
-it.
-For example, by using [tiged]:
-
-```bash
-tiged uenob/vite-plugin-minissg/template/preact my_project
-```
-
-After that, change directory to the new directory and install all
-dependencies by the `npm` command:
-
-```bash
-cd my_project
-npm install
-```
-
-The following scripts are initially available:
-* `npm run build` for static site generation for production.
-* `npm run serve` for preview of the build result.
-* `npm run dev` for starting Vite's dev server.
-
-## Getting Started from Scratch
-
-### Hello, World
-
-To start a Minissg project without any template,
-install Vite and Minissg by your favorite package manager:
-
-```bash
-npm install vite vite-plugin-minissg
-```
-
-And then, put Minissg in the `plugins` list of `vite.config.js`
-and specify at least one entry script in `build.rollupOptions.input`.
-
-```js
-import { defineConfig } from "vite"
-import minissg from "vite-plugin-minissg"
-
-export default defineConfig({
- build: {
- rollupOptions: {
- input: "index.html.js" // put a script file here
- }
- },
- plugins: [
- minissg({
- // put your configuration here
- })
- ]
-})
-```
-
-Write the following code and save it in `index.html.js`:
-
-```js
-export default `
-
-
My first Minissg site
-
Hello, Vite + Minissg!
-`;
-```
-
-We are now ready to build a site.
-Run `vite build` by your favorite package manager:
-
-```bash
-npx vite build
-```
-
-Vite runs twice automatically with the following message and generates
-an `index.html` file in `dist` directory:
-
-```
-vite v4.4.4 building SSR bundle for production...
-✓ 2 modules transformed.
-dist/index.html.mjs 0.18 kB
-dist/assets/lib-d99b01dc.mjs 0.33 kB
-✓ built in 146ms
-vite v4.4.4 building for production...
-✓ 1 modules transformed.
-dist/index.html 0.12 kB │ gzip: 0.11 kB
-✓ built in 16ms
-```
-
-The content of `dist/index.html` should be something like the
-following, which is exactly same as the string literal written in
-`index.html.js`:
-
-```html
-
-
- My first Minissg site
-
Hello, Vite + Minissg!
-
-```
-
-### Previewing and Dev Server
-
-You can use Vite's dev server and preview server for the website
-development.
-To view your site with live reloading, run Vite's Dev Server
-by the following command:
-
-```bash
-npx vite
-```
-
-To preview the production site generated by `vite build`, execute the
-following command:
-
-```bash
-npx vite preview
-```
-
-See Vite's manual for details of these commands.
-
-### Multiple Page Generation
-
-To generate multiple pages, do one of the following:
-
-1. Write a new file, say `hello.txt.js`,
-
- ```js
- export default "Hello\n";
- ```
-
- and add it to `build.rollupOptions.input`.
-
- ```js
- import { defineConfig } from "vite"
- import minissg from "vite-plugin-minissg"
-
- export default defineConfig({
- build: {
- rollupOptions: {
- input: ["index.html.js", "hello.txt.js"]
- }
- },
- plugins: [minissg()]
- })
- ```
-
-2. Define `entries` function in `index.html.js` instead of the `default`
- export and indicate multiple routes in it.
-
- ```js
- export const entries = () => ({
- 'index.html':
- {
- default: `
-
- My first Minissg site
-
Hello, Vite + Minissg!
- `
- },
- 'hello.txt': { default: "Hello\n" }
- });
- ```
-
-### Using a Component Library
-
-The page construction can be done with a component library.
-For your convenience, Minissg provides _renderers_ that
-serialize components into HTML file contents.
-Here, we use [React] to do the same thing as the above.
-First of all, install React and its Vite plugin by the following
-command:
-
-```bash
-npm install react react-dom @vitejs/plugin-react @minissg/render-react
-```
-
-Write `vite.config.js` as follows:
-
-```js
-import { defineConfig } from "vite"
-import minissg from "vite-plugin-minissg"
-import react from "@vitejs/plugin-react" // ADDED
-import minissgReact from "@minissg/render-react" // ADDED
-
-export default defineConfig({
- build: {
- rollupOptions: {
- input: "./index.html.jsx?render" // MODIFIED. NOTE: "./" is mandatory
- }
- },
- plugins: [
- minissg({
- render: {
- "**/*.jsx": minissgReact() // ADDED
- },
- plugins: () => [react()] // ADDED
- })
- ]
-})
-```
-
-The above config includes three important changes from the previous
-one:
-1. Specify a `*.jsx` file in `build.rollupOptions.input` with
- `?render` query.
- The `?render` query indicates that the component exported by this
- file must be serialized by the renderer specified in Minissg's
- `render` option.
-2. Associate `*.jsx` files to the renderer of React components
- (`minissgReact`) by setting Minissg's `render` option.
-3. Add the React plugin to Minissg's `plugins` option of the above
- form, not in that of Vite's config.
- The plugins put here are included in both the server-side and
- client-side run of Vite, whereas plugins specified in Vite's config
- are used only in the server-side run.
-
-Write `index.html.jsx` like this:
-
-```jsx
-export default function() {
- return (
-
- My first Minissg site
-
Hello, Vite + Minissg + React!
-
- )
-};
-```
-
-Run `vite build` and find `dist/index.html` created from the JSX file.
-
-### Authoring with Markdown
-
-Minissg does not provide any capability to deal with Markdown files,
-but you can combine it with your favorite Markdown libraries.
-Say [@mdx-js/rollup] for such a Markdown processor.
-The Vite config must be extended as follows:
-
-```js
-import { defineConfig } from "vite"
-import react from "@vitejs/plugin-react"
-import mdx from "@mdx-js/rollup" // ADDED
-import minissg from "vite-plugin-minissg"
-import minissgReact from "@minissg/render-react"
-
-export default defineConfig({
- build: {
- rollupOptions: {
- input: "./index.html.md?render" // MODIFIED
- }
- },
- plugins: [
- minissg({
- render: {
- "**/*.{jsx,md}": minissgReact() // MODIFIED
- },
- plugins: () => [
- react(),
- mdx() // ADDED
- ]
- })
- ]
-})
-```
-
-Then, write a markdown file named `index.html.md` with the following
-content:
-
-```markdown
-# My first Minissg site
-Hello, Vite + Minissg + MDX!
-```
-
-And execute `vite build` to generate the page.
-
-## How It Works
-
-### Vite Runs Twice
-
-Minissg actually does the following:
-
-1. Run Vite in SSR mode and bundle all the files specified in
- `build.rollupOptions.input` into a single JavaScript program.
-2. Traverse file dependencies in the generated program and determine
- the set of client-side codes and style sheets for each page to be
- generated.
-3. Execute the generated program and obtain the list of pages and
- their contents to be generated.
-4. Run Vite again to generate client-side codes, style sheets, and
- assets.
-
-In what follows, we refer to the first and second run of Vite as
-_server-side run_ and _client-side run_, respectively.
-We also refer to the program generated by or given to the first run
-as _server-side code_.
-
-For integrity between the two runs, Minissg loads server-side code
-not only in server-side run but also client-side run.
-Loading server-side code in client-side run is needed to yield assets
-that are referred only from server-side code or are generated by some
-server-side plugins and used in client-side code.
-Assets generated in server-side run are all discarded for integrity.
-Only the files generated by client-side run are left in the
-destination site.
-
-### Module Tree
-
-Server-side code consists of a collection of _modules_, which
-constitute the hierarchy of files in the website to be generated.
-The variation of a module is defined as follows in TypeScript:
-
-```typescript
-type Module =
- | { entries: (arg: EntriesArg) => Module | PromiseLike }
- | { default: Content | PromiseLike }
- | Record>
- | Iterable<[string, Module | PromiseLike]>;
-
-export type Content =
- | string
- | ArrayBufferLike
- | ArrayBufferView
- | Blob
- | null
- | undefined
-```
-
-The definition of `EntriesArg` will be given later in Contextual
-Information of Modules section.
-
-The `Module` type is the type of modules expected by Minissg.
-Intuitively:
-
-1. A module may have `entries` function that returns another module.
- This allows the module to delegate file generation to another
- module.
-2. A module may also have `default` value that gives Minissg the
- content of a destination file.
- The content can be given in several forms including string,
- Uint8Array, ArrayBuffer, and Blob.
- Except for nullish values, `Content` can be included in an argument
- of `Blob` constructor.
- This allows modules to generate any kind of files from various
- sources; for example, a module can download something by fetch
- API and pass its response as a Blob to Minissg.
- The `null` or `undefined` content means "not found."
- If a module have both `entries` and `default`, `entries` has precedence
- and `default` is ignored.
-3. A module may also be an Iterable object that enumerates multiple
- routing.
- In this case, each item in the Iterable object must be a pair
- (array with two elements) of a string and module, where the string
- is a relative path that will be joined with the name of currently
- requested file.
- See Static Routing section below for the details of name
- concatination.
-
-Empty module is regarded as `{ default: null }`.
-
-Through the `entries` functions and mapping objects, the collection of
-modules constitute a tree structure.
-The root of this tree is the _top-level module_, which is a virtual
-module generated in accordance with Vite's `build.rollupOptions.input`
-config.
-The top-level module is constructed depending on the structure of
-`build.rollupOptions.input` by the following rules:
-
-1. If `build.rollupOptions.input` is a single string, the top-level
- module is a singleton mapping from the name of the given file
- to the module provided by the file.
- For example,
- ```js
- { build: { rollupOptions: { input: "index.html.js" } } }
- ```
- means that `index.html.js` is the module providing the content of
- `index.html` file.
- This is equivalent to the following module:
- ```js
- { "index.html": { entries: () => import("./index.html.js") } }
- ```
-2. If it is an array of strings, the top-level modules is a mapping
- from their names to their modules.
- For example,
- ```js
- { build: { rollupOptions: { input: ["index.html.js", "hello.txt.js"] } } }
- ```
- means the following module:
- ```js
- {
- "index.html": { entries: () => import("./index.html.js") },
- "hello.txt": { entries: () => import("./hello.txt") }
- }
- ```
-3. If it is an object, Minissg uses it as the mapping from names to
- modules.
- For example, if the following config is given,
- ```js
- { build: { rollupOptions: { input: { "index.html": "index.js" } } } }
- ```
- Minissg uses `index.js` to generate `index.html`, i.e., the
- top-level module should look like the following:
- ```js
- { "index.html": { entries: () => import("./index.js") } }
- ```
-
-### Static Routing
-
-Each module is uniquely associated to a name of a destination file.
-In what follows, we refer to such a name as the _name_ of a module.
-
-The name of the top-level module is always `index.html`.
-For other modules, which must be child modules of a module,
-their names are computed from the name of their parent module by the
-following rule:
-
-1. The name of the module returned by `entries` function is same
- as that of the module owning the `entries` function.
-2. The name of a module associated to a relative path in a parent
- module is obtained by appending the relative path to the end of the
- name of the parent module.
- The appending is done with equating path fragment `index.html` with
- empty fragment.
- Detailed procedure of this appending is the following:
- 1. If the name of the parent module ends with `index.html` fragment,
- eliminate it.
- 2. If the relative path includes `.` fragment, eliminate all of
- them.
- 2. If the name of the parent module does not end with `/`
- and the relative path is not empty, add `/` to the beginning of
- the relative path.
- 4. Concatenate the output of the parent module and the relative
- path in this order.
- 5. If the concatenation result ends with `/`, append `index.html`
- to the end of it.
-
-For static site generation, Minissg visits all of the modules
-reachable from the top-level module.
-During this traversal, Minissg calls all `entries` functions
-to determine the entire set of modules.
-After that, for each module that have effective `default` value,
-Minissg generates a file whose name is the name of the module and
-whose content is the `default` value.
-
-Note that the name of a module is not always unique.
-If two modules has the same name and effective `default` values, the
-first-visited one precedes another.
-Strictly speaking, the precedence is determined by the pre-order of
-the entire module tree.
-Intuitively, the order of precedence is the order of modules appearing
-in a parent module.
-
-A simple but powerful way to organize multiple modules is to use
-Vite's `import.meta.glob` feature.
-The following example defines the `entries` function that
-includes all of the `*.md` files in the `pages` directory to
-generate `*/index.html` files from them.
-
-```js
-const mdFiles = import.meta.glob("./**/*.md", { query: { render: "" } });
-
-// transform filenames *.md to */ and import functions to entries functions
-const modules = Object.entries(mdFiles).map(([filename, entries]) => {
- return [filename.replace(/\.md$/, "/"), { entries }]
-});
-
-export const entries = () => modules;
-```
-
-By exploiting the fact that `index.html` and `./` fragments in a
-relative path are ignored, you can overlay a module tree with other
-trees.
-This is useful to separate files for each concern regardless of the
-hierarchy of destination files.
-A typical example is, as shown below, to separate the top page from
-other pages that are generated from Markdown files.
-
-```js
-export const entries = () => ({
- // Only the top page has a special construction.
- 'index.html': { entries: () => import("./index.jsx") },
- // But others have the same layout and generated in the same way.
- '.': { entries: () => import("./pages.js") }
-});
-```
-
-### Renderers
-
-Renderer is a Minissg's feature that transforms the default export
-of a file to a content of a generated file.
-To apply a renderer to a file, add `?render` query to the import
-referring to the file.
-
-For example, suppose that we are using Minissg with React.
-We usually write a React component as a separate file, say
-`Count.jsx`, like the following:
-
-```jsx
-import { useState } from "react";
-
-export default function Count({ init }) {
- const [count, setCount] = useState(init ?? 0);
- return (
-
- );
-};
-```
-
-The default export of this file is a React component, which is a
-function, not of type `Content` given in the above type
-definitions.
-Therefore, without any additional conversion, Minissg cannot generate
-a file from this module.
-The purpose of renderers is to provide this kind of conversion.
-By applying the renderer for React components to this file, we
-obtain the serialized string of this component.
-
-To apply a renderer to a file, add `?render` query to its import like
-this:
-
-```js
-import content from "./Count.jsx?render";
-```
-
-The `content` variable contains a PromiseLike object of a string
-that can be accepted by Minissg as a file content.
-
-The association between files and their renderers is given in
-Minissg's `render` option in `vite.config.js`.
-The `render` option associates a glob pattern to a renderer.
-Minissg searches for a renderer of a particular file in accordance with
-this association.
-See Plugin Options section for details of the `render` option.
-
-Minissg provides several renderers for popular component systems
-in separate packages.
-To use renderers, install the following packages and import them in
-`vite.config.js`:
-
-* `@minissg/render-preact` for [Preact] components.
-* `@minissg/render-react` for [React] components.
-* `@minissg/render-solid` for [Solid] components.
-* `@minissg/render-svelte` for [Svelte] components.
-* `@minissg/render-vue` for [Vue] components.
-
-Note that using renderers is not essential;
-you can avoid it by writing your own serializer by your hand and
-include it in server-side code.
-You can even write custom renderers and give it to Minissg through
-Minissg's `render` option.
-See User-defined Renderer and Hydration section for details.
-
-### Style Sheets
-
-Each generated HTML file may have static links to CSS files.
-The set of style sheets of each page is the set of all of the `*.css`
-files (or other style sheet files supported by Vite) imported in
-server-side code in the middle of loading the module corresponding to
-the file.
-
-While this looks similar to Vite's default handing of style sheets,
-Minissg provides more;
-if a dynamic import occurs in the middle of the path to a module,
-dynamically imported `*.css` files are also included in the set of
-style sheets of that module.
-The set of style sheets is computed independently for each module.
-For example, suppose the following three files:
-
-1. `index.html.js`
- ```js
- import "./index.css";
- export const entries = () => ({
- "foo.html" => { entries: () => import("./foo.html.js") },
- "bar.html" => { entries: () => import("./bar.html.js") }
- });
- ```
-2. `foo.html.js`
- ```js
- import "./foo.css";
- export default " ... ";
- ```
-3. `bar.html.js`
- ```js
- import "./bar.css";
- export default " ... ";
- ```
-
-The `index.html.js` file provides the route to two modules
-`foo.html` and `bar.html` provided by `foo.html.js` and `bar.html.js`,
-respectively.
-The `foo.html.js` and `bar.html.js` have `default` export and
-consequently `foo.html` and `bar.html` are generated as a result.
-The set of style sheets of these two HTML files depends on the path of
-execution to these modules as follows.
-
-1. Regardless of the two modules, `index.html.js` must be executed
- and therefore `index.css` is inevitably imported.
- Consequently, a link to `index.css` is included in both `foo.html`
- and `bar.html`.
-2. `foo.css` is imported only when `foo.html.js` is dynamically
- imported.
- Hence, `foo.css` is additionally included in `foo.html`.
- Since dynamic import of `foo.html.js` is not relevant to
- `bar.html`, `foo.css` is not included in `bar.html`.
-3. Similarly, `bar.css` is included only in `bar.html`.
-
-As a result, the following two links are included in `foo.html`:
-
-```html
-
-
-```
-
-and are the following in `bar.html`:
-
-```html
-
-
-```
-
-Note that these tags are not what is included exactly in the final
-output.
-Vite transforms `*.css` files, bundles them appropriately,
-and then injects the optimized result in the generated HTML files.
-
-### Client-side Code
-
-All the modules in server-side code are just for server-side file
-generation and therefore are not left in the output.
-To include some code in the generated site in order to execute it
-on client side, import it in server-side code with `?client` query.
-
-For example, suppose the following two files:
-
-1. `index.html.js`
- ```js
- import "./foo.js?client";
- export default `
- Hello`;
- ```
-2. `foo.js`
- ```js
- document.body.appendChild(document.createTextNode('Hi!'));
- ```
-
-By building the site up with `index.html.js`, we find `dist/index.html`
-that refers a script like the following:
-
-```html
-
-
-
- Hello
-
-
-
-
-```
-
-The set of scripts to be included in each page is determined by the
-same manner as style sheets;
-all the imports with `?client` query executed during loading a module
-is included in the output of that module.
-
-The client-side code is processed by Vite as well as server-side code.
-This means that you can write client-side code in any language
-that Vite (or one of its plugin) supports.
-Vite translates client-side code and minifies all its chunks as usual.
-Minissg does not throw anything more at Vite, but does not take
-anything more from Vite.
-
-### Partial Hydration
-
-Minissg provides a simple partial hydration mechanism
-in the sense of [island architecture] for several component systems.
-To enable partial hydration for a component, import the component
-with `?hydrate` query.
-The code imported with `?hydrate` query is included in both
-server-side and client-side code to embed its initial view in the
-static file and to hydrate the view in the web browsers.
-
-As an example, here we attempt to use the `Count.jsx` presented in
-Renderer section.
-At first, To enable partial hydration feature for `*.jsx` files,
-associate `**/*.jsx` to React renderer in Minissg plugin's `render`
-option.
-
-By importing `Count.jsx` with `?hydrate` query as follows, we turn on
-the hydration of this component:
-
-```jsx
-import Count from "./Count.jsx?hydrate";
-
-export default function() {
- return ;
-};
-```
-
-This results in the following output:
-
-```html
-
-
-
-
-
-
-
-
-
-
-```
-
-The `/assets/hydrate-7c5f4dec.js` file is the top-level client-side
-code that hydrates the `Count` component.
-It searches for the element with `data-hydrate="g_zZoKsE"` attribute
-for the target of hydration, where `"g_zZoKsE"` is the unique
-identifier of the `Count` component.
-The `data-hydrate-args` attribute holds the serialized argument of
-`Count` component, which is passed to the component for hydration.
-
-Note that this is not the only way for hydration in Minissg.
-You can hydrate a component in a different way than `?hydrate` by
-writing it in your program.
-Minissg does not force you anything.
-
-## Advanced Features
-
-### Configuring Client-side Run
-
-As described above, Vite runs twice for static site generation.
-The two runs are for different purposes and therefore may have
-different settings.
-The top-level config of `vite.config.js` is used only in server-side
-run, not in client-side run.
-The config of client-side run is automatically generated by Missing
-based on the top-level config and the result of server-side run.
-To tweak the config of client-side run, Minissg provides `config`
-option that will be merged into the config of client-side run.
-For example, to turn on the minify option only in client-side run,
-write it in the `config` option as follows:
-
-```js
-import { defineConfig } from "vite"
-
-export default defineConfig({
- build: {
- rollupOptions: {
- input: "./index.html.js"
- }
- },
- plugins: [
- minissg({
- config: {
- build: {
- minify: true // enable minify only on client-side run
- }
- }
- })
- ]
-})
-```
-
-Minissg computes the config of client-side run from the following
-three sources: the top-level config, the results of server-side run,
-and the `config` option of the Minissg plugin.
-Almost all the settings in the top-level config are inherited to
-client-side run except for the following:
-
-* `plugins` are never shared between the two runs.
- Plugins must be instantiated for each run.
- To enable the same set of plugins in both runs, which is a usual
- requirement, duplicate it in both the top-level config and Minissg's
- `config`, as seen in the following example:
- ```js
- import { defineConfig } from "vite"
- import react from "@vitejs/plugin-react"
-
- export default defineConfig({
- ...
- plugins: [
- react(), // plugin for server-side run
- minissg({
- ...
- config: {
- plugins: [react()] // plugin for client-side run
- }
- })
- ]
- })
- ```
- As a shorthand of this, Minissg provides `plugin` option for
- convenience.
- Set it to a function returning an array of plugins and the function
- will call twice to instantiate plugins for each runs.
- The following example is equivalent to the above:
- ```js
- import { defineConfig } from "vite"
- import react from "@vitejs/plugin-react"
-
- export default defineConfig({
- ...
- plugins: [
- minissg({
- ...
- plugins: () => [react()] // plugin for both runs
- })
- ]
- })
- ```
-* The following options of the top-level config are overwritten in
- client-side run with the result of server-side run: `root`, `base`,
- `mode`, `build.emptyOutDir`, and `build.rollupOptions.input`.
- You can overwrite them again by setting them in the `config` option,
- but it usually breaks the integrity of two runs; do it at your own
- risk.
-
-### Generating Data for Client-side Code
-
-Minissg allows server-side code to generate specific data for each
-client-side code.
-For this purpose, importing with `?client` query provides us with a
-mutable object that holds data to be passed to the client-side code.
-Client-side code can refer to such data by importing a virtual module
-named `virtual:minissg/client`.
-
-Suppose that we have a client-side code `foo.js` and attempt to pass
-some data to it from server-side code.
-This can be done by manipulating the default export of
-`foo.js?client`.
-For example, the following code
-
-```js
-import data from "./foo.js?client";
-
-data["bar"] = "baz";
-```
-
-puts a string `"baz"` with the key `"bar"` in the object to be passed
-to `foo.js`.
-Minissg serialize this object in JSON and generate a client-side
-module that provides the JSON object.
-Because of this implementation, the values put in this object must be
-serializable in JSON.
-
-In client-side code, import `virtual:minissg/client` in `foo.js` to
-have an access to the object passed from the server-side code.
-For example, in `foo.js`, the following client-side code
-
-```js
-import data from "virtual:minissg/client";
-
-console.log(data["bar"]);
-```
-
-will print `baz` in the web browser's console.
-
-The object imported by `?client` query has `id` property as its
-initial content.
-The value of the `id` property is a string of a unique identifier of
-this client-side module.
-You can overwrite or delete it if it is not needed.
-A supposed usage of this identifier is to find particular HTML elements
-generated by server-side code from client-side code.
-
-### Renderer for a Module Itself
-
-Sometimes it is convenient if a module can obtain the renderer
-associated to itself.
-A special module named `virtual:minissg/render` provides it.
-The default export of `virtual:minissg/render` is the rendering
-function of the importer.
-The actual type of the rendering function depends on its definition.
-
-A typical example of using this feature is that a module has multiple
-children of the same type and renders them in the same way.
-The following is an example of JSX file that aggregates MDX files:
-
-```jsx
-import render from "virtual:minissg/render";
-
-// common layout for all MDX files
-const Layout = ({ children }) => {
- return {children};
-};
-
-const pages = import.meta.glob("./**/*.mdx");
-const modules = Object.entries(pages).map(([filename, load]) => {
- const entries = async () => {
- // load an MDX file and compose it with Layout.
- const Component = await load();
- const Page = () => ;
- // serialize the composed component.
- return render(Page);
- };
- return [filename.replace(/mdx$/, "html"), { entries }]
-});
-
-export const entries = () => modules;
-```
-
-### User-defined Renderers and Hydration
-
-A renderer is actually an object representing a collection of
-functions that return code in a string.
-Minissg calls one of these function in accordance with `?render`
-and/or `?hydrate` queries to obtain the code that implements the
-feature specified by those queries.
-The type of renderers is given below in TypeScript:
-
-```typescript
-type Renderer = {
- render?: {
- server?: (arg: { parameter: string }) => string | PromiseLike;
- client?: (arg: { parameter: string }) => string | PromiseLike;
- };
- hydrate?: {
- server: (arg: HydrateArg) => string | PromiseLike;
- client: (arg: HydrateArg) => string | PromiseLike;
- };
-};
-
-type HydrateArg = {
- id: string;
- moduleId: string;
- parameter: string;
-};
-```
-
-A renderer can provide two properties `render` and `hydrate`, which
-are associated to `?render` and `?hydrate` queries, respectively.
-Both of them may have two variants: `server` for server-side code
-generation, and `client` for client-side.
-All of the functions in a renderer must return a string of the source
-code of an ES6 module.
-Except for `hydrate.server`, the code must be written in vanilla
-JavaScript.
-The code returned by `hydrate.client` must be written in the same
-language as the file that `?hydrate` query is given.
-
-Each function in `render` must return a string of the source code of
-an ES6 module whose default export is the rendering function, which
-serializes the given data or component into a format specified in
-the `Content` type described in Module Tree section.
-The `render` functions takes one argument, namely `parameter`, which
-holds the value of `?render` query.
-
-The code generated by `hydrate.server` must be a component that wraps
-the original component with hydration target container.
-The `hydrate.server` function is given an argument of `HydrateArg`
-type, which has three properties:
-`id` for a unique identifier of this component,
-`moduleId` for the identifier of the original file, and
-`parameter` for the value of `?hydrate` query.
-Both `hydrate.server` and `hydrate.client` functions are called with
-the identical argument for each import.
-
-The code generated by `hydrate.client` must be a JS code that can be
-embedded in an `
+
+
+