Container Orchestration
ArticlesCategories
Environment & Energy

How to Migrate Your Static Websites to Dart and Jaspr: A Step-by-Step Guide

Published 2026-05-03 15:42:22 · Environment & Energy

Introduction

If your organization maintains multiple websites built on different static-site generators—like Eleventy (Node.js) for documentation and Wagtail (Python) for a marketing site—you know the pain of a fragmented stack. Each tool requires distinct expertise, and adding interactive features (code samples, quizzes) often means writing brittle, one-off JavaScript. The Flutter team faced exactly this problem across dart.dev, flutter.dev, and docs.flutter.dev. Their solution? Migrate everything to Jaspr, an open-source Dart web framework that supports static site generation, server-side rendering, and client-side interactivity—all in one language. This guide walks you through the same migration process, step by step, so you can unify your own web properties under a single, Dart-powered stack.

How to Migrate Your Static Websites to Dart and Jaspr: A Step-by-Step Guide

What You Need

  • Dart SDK (version 3.0 or later) – Download from dart.dev
  • Jaspr package (latest) – install via dart pub global activate jaspr_cli
  • Existing static site content (Markdown, HTML, or any source material)
  • A code editor (VS Code with Dart extension, or IntelliJ)
  • Basic familiarity with Dart and Flutter widget concepts (helpful but not required)
  • A version control system (Git) for tracking changes

Step-by-Step Migration Guide

Step 1: Assess Your Current Stack and Identify Fragmentation

Before migrating, map out every website in your portfolio. Note the technologies behind each: static-site generators (Eleventy, Hugo, Jekyll), CMS platforms (Wagtail, WordPress), and any interactive components (custom JS, iframes). The Flutter team found dart.dev and docs.flutter.dev on Eleventy while flutter.dev used Wagtail. This fragmentation meant contributors needed both Node.js and Python expertise. List all dependencies, content types, and interactive features. Prioritize unifying the stack to reduce friction and improve developer experience.

Step 2: Set Up Dart and Jaspr Environment

Install the Dart SDK and the Jaspr CLI globally. Create a new Jaspr project using jaspr create my-site. This scaffolds a project with support for client-side rendering (CSR), server-side rendering (SSR), and static site generation (SSG). Familiarize yourself with Jaspr's component model—it mirrors Flutter widgets, so if you know StatelessWidget, you'll feel at home. For example, a Jaspr component looks like this:

class FeatureCard extends StatelessComponent {
  const FeatureCard({required this.title, required this.description, super.key});
  final String title;
  final String description;
  @override
  Component build(BuildContext context) {
    return div(classes: 'feature-card', [
      h3([text(title)]),
      p([text(description)]),
    ]);
  }
}

This direct transfer of Flutter skills is a key advantage of Jaspr.

Step 3: Port Your Static Content to Jaspr Components

Start with one website (e.g., your documentation site). Export existing content as Markdown or raw HTML. In Jaspr, create corresponding components for each page layout. Use Jaspr's ServerStaticComponent or StatelessComponent to render pages at build time. For content-heavy sections, leverage Jaspr's Markdown integration or define custom components for code blocks, notes, and tables. Reuse components across pages to reduce duplication. For flutter.dev, the team rebuilt page templates using Jaspr's HTML-compatible elements. Ensure that all internal links and assets (images, CSS) are correctly referenced.

Step 4: Implement Interactive Features without Breaking the Build

One of the biggest pain points in static sites is adding interactivity. With Jaspr, you can embed interactive components that run on the client side. For example, create a quiz component using ClientComponent that tracks state with useState. Jaspr compiles these to JavaScript via Dart2JS or dart2wasm, making them work seamlessly on the client. The Flutter team replaced one-off DOM logic by wrapping interactive elements in Jaspr components, like richer code samples with runnable examples and in-page tutorials. This step might require rewriting existing JS widgets in Dart, but the payoff is a unified codebase where all interactivity lives in the same language.

Step 5: Configure Static Site Generation and Build

Jaspr excels at SSG. In your project, configure the build to generate static HTML for all pages. Use Jaspr's routing system to define URLs, then run jaspr build --static. This produces a set of HTML files ready to deploy to any static hosting (Netlify, Firebase, S3). The Flutter team used this approach to generate their documentation and marketing sites. During build, Jaspr renders each component server-side (or at build time) to produce full HTML, ensuring search engine friendliness and fast initial load. Test the build locally to catch any broken links or missing content.

Step 6: Test, Integrate, and Deploy

After building, verify every page renders correctly. Check interactivity by loading sites in a browser and clicking through quizzes, code samples, and navigation. Validate against the original site for content parity. Set up a CI/CD pipeline (e.g., GitHub Actions) that runs jaspr build --static and deploys to your hosting provider. The Flutter team replaced their separate Node.js and Python deployments with a single Dart-based pipeline, reducing maintenance overhead. Monitor performance using Lighthouse or WebPageTest; Jaspr's static output typically scores highly. Over time, migrate remaining sites (one by one) until your entire web presence runs on one stack.

Tips for a Smooth Migration

  • Start small – Pick the simplest site first (e.g., a small documentation area) to learn the Jaspr workflow before tackling complex marketing pages.
  • Leverage your Flutter experience – Jaspr's component model intentionally mirrors Flutter widgets. Translate widget trees directly to Jaspr DOM trees with div, span, and other HTML tags.
  • Reuse Dart packages – If your existing infrastructure already uses Dart for tooling or backend services, import those same packages in your Jaspr project. The Flutter team benefited from sharing data models and utilities.
  • Prioritize interactivity bits – Identify which interactive elements are most critical (e.g., runnable code samples) and implement those first as Jaspr client components. Phase out legacy JS gradually.
  • Use Jaspr's built-in SSR for previews – During development, run jaspr serve for hot reload and server-side rendering to see changes instantly.
  • Don't rewrite everything at once – A staged migration kept the Flutter team sane. You can host both old and new sites side by side with a proxy or feature flag until the new site is fully validated.
  • Document your architecture – The unified stack makes it easier for new contributors. Write guidelines on how to add pages and components using Dart only.

Conclusion

Migrating three major websites from a fractured mix of Eleventy and Wagtail to a single Dart and Jaspr stack gave the Flutter team a consistent developer experience, reduced onboarding friction, and simplified interactivity. By following these steps—assessing your current stack, setting up Jaspr, porting content, adding interactive components, configuring SSG, and deploying—you can achieve the same unification. The result is a web presence that's easier to maintain, extend, and contribute to, all in one language your team already knows.