Proof of concept for a freestanding SSG with islands using Vue
  • TypeScript 83.6%
  • Vue 12.2%
  • JavaScript 4.2%
Find a file
Hornwitser e161a6980c Add optional pathname hyphentation
This make it possible to have your vue component based pages to be named
like SomePage.vue while having it served under /some-page.html on the
website itself.
2026-06-03 18:24:39 +02:00
.vscode POC implementation of Vue SSG with islands 2026-05-24 23:29:32 +02:00
src Add optional pathname hyphentation 2026-06-03 18:24:39 +02:00
ssg Add optional pathname hyphentation 2026-06-03 18:24:39 +02:00
.editorconfig POC implementation of Vue SSG with islands 2026-05-24 23:29:32 +02:00
.gitattributes POC implementation of Vue SSG with islands 2026-05-24 23:29:32 +02:00
.gitignore Implement building 2026-05-27 20:45:51 +02:00
package.json Implement custom components in markdown 2026-05-29 21:56:33 +02:00
pnpm-lock.yaml Implement custom components in markdown 2026-05-29 21:56:33 +02:00
readme.md Add optional pathname hyphentation 2026-06-03 18:24:39 +02:00
ssg-config.ts Add optional pathname hyphentation 2026-06-03 18:24:39 +02:00
tsconfig.json POC implementation of Vue SSG with islands 2026-05-24 23:29:32 +02:00

vuebox

A POC for a free standing implementation of SSG with islands support using Vue.

Running

  1. Install dependencies with pnpm install
  2. Run node --import ./ssg/node-hooks.ts ssg/watch.ts to start the development server in watch mode. You can also use serve.ts instead of watch.ts to run the development server without restarting on file changes..
  3. Navigate to http://localhost:8000 to see it in action.

Note

if using bun replace node --import ./ssg/node-hooks.ts with bun --preload ./ssg/bun-plugin.ts. Bun is not tested nor supported, use at your own risk.

Building

Build the page with node --import ./ssg/node-hooks.ts ssg/build.ts. This will output the files that are needed to host the website into the ./public folder.

To preview the built website without having to set up a web server, run node ./ssg/preview, it'll server files from the ./public folder and set the correct Content-Type headers.

Hosting

To host the website, copy the files from the ./public folder after running a build into the root folder server by a suitable webserver. You will need to configure the webserver to report a Content-Type of text/javascript for .txt, .md, and .vue files, otherwise component islands will not work.

The content system assumes that "pretty URLs" are not a thing, and that requests to directories redirects to a suitable html file, rather than directly serving an index.html. You should only setup pretty URL rewriting if you know what you're doing and the consequences of doing so.

Pain points

Learned from doing a test migration of a medium sized website from vite-ssg to this project.

  • There is no documentation for how to use this tool.
  • Lack of bundler makes using third party packages difficult and bloated. You have to manually add long and tedious import maps and copy files to the build for it to work.
  • No support for TypeScript
  • No auto component loader (I'm conflicted on this).
  • Islands support only a single element inside them with no content. This is needlessly difficult to work with.
  • No client side access to things like the list of pages.
  • No way to easily generate a list of pages from say 2 different options on the same page. Use case for this would be for example a map page with different floor levels being different pages, but all else stay the same. Or a multi-page table with different columns you can sort by that is entirely static.
  • No way to easily generate a list of pages from a data structure.
  • Need a way to inject build time data like a GIT_REF and process.env.NODE_ENV.
  • Need an easy way to distinguish client side from server side. To support logic like if (CLIENT) {} that avoids touching dom specific API's during the server build.
  • No warnings if you add reactive logic to a static component. Things like @click and onMounted will be completely ignored outside of islands.
  • No asset management means that the build currently "builds" by copying and transforming every file in the src directory. Caching is made difficult by the need to manually make sure files that are changed get a new name.
  • No minification of CSS or JS.
  • Need tools to work with #routing inside islands.
  • Doing advanced transforms like converting a markdown document to a list of sections and rendering each section with arbitrary surrounding data is non-trivial.
  • Watch mode is slow and works by restarting the Node.js server and fully reloading the page every time any file is edited.
  • The browser window stops self updating in watch mode if the server encounters an error due to the error page not having a watch mode script listener.
  • Watch mode occasionally does spurious reloads.
  • Adding page data to vue pages is somewhat annoying.
  • No app-init, makes setting up pinia impossible.
  • Spaces in filenames break the serve server.
  • No support for having a folder for providing files that are to be copied verbatim to the build.