Environment & Energy

How to Unify Your Multi-Site Web Stack Using Dart and Jaspr: A Step-by-Step Migration Guide

2026-05-04 03:41:27

Introduction

Building and maintaining multiple websites with different frameworks and languages can become a significant burden. The Dart team faced this exact challenge: their three primary sites—dart.dev, flutter.dev, and docs.flutter.dev—were each built with separate, non-Dart tools. The documentation sites relied on Eleventy (Node.js), while flutter.dev used Wagtail (Python/Django). This fragmentation made contributions difficult, increased setup friction, and limited code sharing. The solution was to migrate everything to Jaspr, an open-source Dart web framework that supports server-side rendering (SSR), client-side rendering (CSR), and static site generation (SSG). This guide walks you through the same process: from identifying the problem to deploying a unified stack, all using Dart and Jaspr.

How to Unify Your Multi-Site Web Stack Using Dart and Jaspr: A Step-by-Step Migration Guide

What You Need

Step-by-Step Migration to Jaspr

Step 1: Assess Your Current Stack and Identify Pain Points

Before migrating, document each site’s current framework, hosting setup, and content model. Ask yourself:

In the Dart team’s case, the documentation sites used Eleventy (Node.js) and flutter.dev used Wagtail (Python). This fragmented setup forced contributors to switch contexts and limited code reuse. Identifying these friction points will justify and guide your migration.

Step 2: Choose a Unified Framework – Jaspr

Jaspr is a Dart-based web framework that feels natural to Flutter developers. It supports SSR, CSR, and SSG, making it ideal for a mixed site portfolio. Why Jaspr?

Step 3: Set Up the Jaspr Project Structure

Create a new Jaspr project for your main site (e.g., jaspr create my_unified_site). This generates a standard structure with lib/, web/, and pubspec.yaml. For multiple sites, consider a monorepo using Dart packages. For example, you can have:

my-sites/
  shared-components/
  site-dart/
  site-flutter/
  site-docs/

Each site is a separate Jaspr project that imports widgets from shared-components. This allows you to reuse code across all sites while keeping content separate.

Step 4: Port Your Content and Components to Jaspr

Start with a static version of your most complex page. Jaspr components look like this:

class FeatureCard extends StatelessComponent {
  final String title;
  final String description;

  FeatureCard({required this.title, required this.description, super.key});

  @override
  Component build(BuildContext context) {
    return div(classes: 'feature-card', [
      h3([text(title)]),
      p([text(description)]),
    ]);
  }
}

If you already have Flutter knowledge, this syntax will be familiar. For each page:

Step 5: Implement Server-Side Rendering or Static Generation

Jaspr supports both SSR (for dynamic content) and SSG (for fast, cached pages). For documentation sites with mostly static content, SSG works well. For flutter.dev with CMS-like features, SSR might be better. Configure in jaspr.config.yaml:

modes:
  static: true  # enable static generation for specific routes
  server: true  # enable server-side rendering for others

You can even combine both: statically generate most pages and use SSR for interactive components like quizzes or code executors.

Step 6: Add Interactivity with Dart

The team wanted richer code samples and quizzes. With Jaspr, you can add client-side interactivity using Dart event handlers and state management. For example, a quiz component:

class Quiz extends StatefulComponent {
  @override
  State createState() => _QuizState();
}

class _QuizState extends State {
  int score = 0;

  void answerCorrect() {
    setState(() => score++);
  }

  @override
  Component build(BuildContext context) {
    return div([
      button(onClick: answerCorrect, [text('Correct')]),
      p([text('Score: $score')]),
    ]);
  }
}

This eliminates the need for separate JavaScript files and keeps all logic in Dart.

Step 7: Test, Iterate, and Deploy

Run jaspr serve locally to preview your unified sites. Ensure all links, assets, and interactive features work across devices. Once satisfied, build for production:

jaspr build

This generates a build/ folder with static files (if using SSG) or a server bundle (if using SSR). Deploy to your preferred platform. The Dart team used the same deployment pipelines but simplified them because only one toolchain was needed.

Tips for a Smooth Migration

By following these steps, you can replicate the Dart team’s success: a unified, Dart-only web stack that simplifies contributions, reduces cognitive load, and opens the door to richer interactive features. Jaspr makes it possible to bring the power of Flutter to the DOM without leaving your language.

Explore

57 Nations Forge a Clear Roadmap to End Fossil Fuel Dependence at Landmark Colombia Summit Meta’s AI Pre-Compute Engine: Unlocking Tribal Knowledge Across Massive Codebases Fast16: The Secret US-Made Malware That Silently Sabotaged Iranian Systems New CSS contrast-color() Function Automates Text Contrast for Web Accessibility Everything About Open source package with 1 million monthly downloads stole u...