React, Vue and MDX
Components when you want them, JavaScript only where you need it.
vagejs is a static site generator that lets you build pages with React and Vue components and write content in MDX, then turns all of it into plain HTML when it builds your site. Visitors get no JavaScript unless you mark a React component interactive, and then only on the pages that use it.
npm create vagejs@latest my-site- 0 KBJavaScript from layouts and MDX pages
- ~215 KBReact itself
- 100 KBDefault JavaScript budget per page
What you can build with components
Components are a nice way to build a site: write a pricing card once, use it on ten pages. The usual cost is JavaScript that every visitor downloads, even for parts of the page that never change. We keep the components and drop that cost.
Layouts as React or Vue components
Write
src/layouts/default.tsxordefault.vue. A React layout gets the same data as a TypeScript one: the page, the site, the list of pages and your menus. Visitors get plain HTML and no JavaScript.MDX pages
MDX is Markdown that can use React components. Write
src/pages/pricing.mdxand import any component fromsrc/components/. It becomes plain HTML too, with no JavaScript.Interactive React islands
Add
client:load,client:visibleorclient:idleto a React component and it runs in the browser. JavaScript goes only to the pages that use one.
Islands only where you ask
An island is one interactive part on an otherwise static page. It's rendered to HTML first, so visitors see the component right away and the page works while its JavaScript loads.
import Calculator from "../components/Calculator.tsx";
<Calculator client:load rate={4.5} />| Directive | Starts |
|---|---|
client:load |
as soon as the page loads |
client:visible |
when it scrolls into view |
client:idle |
when the browser has nothing else to do |
With client:visible, visitors who never scroll that far never download the component.
MDX is checked like Markdown
MDX pages and component layouts get the same treatment as Markdown pages: titles, descriptions, sitemap entries, structured data, and vage check for broken links, hidden links and links to websites you haven't approved.
---
title: Pricing
description: Plans and prices.
---
import PlanCard from "../components/PlanCard.tsx";
# Pricing
<PlanCard name="Team" price="$20 a month" />One difference: an MDX page is code, like a layout. It runs when the site is built, so vagejs can't clean it up the way it cleans HTML in Markdown pages. Keep MDX for content you'd trust in a layout.
Who React, Vue and MDX in vagejs are for
Teams that already think in React
Reuse the components and habits you have, without turning a content site into an app.
Sites that need one or two interactive parts
A price calculator, a filter or a short quiz, on a site that's otherwise static.
Anyone moving from a component framework
Keep your layouts as components, and gain built-in checks and SEO files along the way.
What it costs
Sites that don't use components install nothing extra. Add React, Vue or MDX when you need them; if one is missing, the build tells you the exact command to install it.
An island does cost JavaScript. vage audit counts it on every page, including React itself (about 215 KB), which is over the default 100 KB budget. So adding one is a decision you make, not an accident. For many jobs, plain HTML does the same: a <details> element opens and closes, and a form can send without any script.
npm install react react-dom # React layouts
npm install --save-dev @mdx-js/mdx # plus React, for MDX pages
npm install vue && npm install --save-dev @vitejs/plugin-vue # Vue layoutsThe limits, for now
Here's what doesn't work yet, so you can plan around it.
- Interactive components are React only. Vue components work in layouts, as HTML.
- Interactive components take plain data (text, numbers, lists) and can't contain other interactive components.
- CSS imported inside components isn't collected. Put your styles in
public/and link them from the layout.
If you need islands in Vue or Svelte, or a site that's mostly interactive, see how vagejs compares with other tools.
More on React, Vue and MDX in vagejs
React support arrived in version 0.10 for layouts and MDX pages, and in 0.11 for interactive components.
- Step by step: add an interactive React component to a static site
- Every option and rule: React, Vue and MDX in the docs
- Other features: all vagejs features
Questions about React, Vue and MDX
Do I need to install React to use vagejs?
No. A site without components doesn't need React, Vue or MDX at all. Install each one when you start using it. If a page or layout needs a package that's missing, the build stops and prints the exact install command.
Why doesn't useState or onClick do anything in my component?
Only components marked with client:load, client:visible or client:idle run in the browser. Everything else is turned into HTML once, when the site is built, so state, effects and click handlers do nothing there. Mark the component interactive if it needs them.
How do I style my components?
Put your CSS in public/ and link it from your layout. CSS inside components, such as a Vue <style> block or import "./card.css", isn't added to the site.
Can I edit MDX pages in the browser editor?
Not yet. The editor that npm run dev opens lists .md pages only, so edit .mdx pages in your code editor.
Start with one command.
You'll have a site running in a minute.
npm create vagejs@latest my-site