jaspr_converter 1.0.0 copy "jaspr_converter: ^1.0.0" to clipboard
jaspr_converter: ^1.0.0 copied to clipboard

Convert Jaspr component trees to HTML and parse HTML back into Jaspr components.

jaspr_converter #

Utilities for converting between Jaspr Component trees, HTML markup, and generated Jaspr component source. It is especially useful when you want to build reusable Jaspr layouts and render them into plain HTML, including dynamic newsletter and email templates.

Features #

  • Render a Jaspr Component tree to HTML.
  • Parse raw HTML, a remote URL, or a local HTML file into Jaspr components.
  • Generate stateless or stateful Jaspr component source from parsed HTML.
  • Persist generated .html and .dart output.
  • Render dynamic newsletters built with Jaspr and async data into HTML for email delivery.
  • Use extension helpers for direct component-to-HTML and component-to-source conversions.

Installation #

dart pub add jaspr_converter

Import the package with Jaspr:

import 'package:jaspr/dom.dart';
import 'package:jaspr/server.dart';
import 'package:jaspr_converter/jaspr_converter.dart';

When rendering on the Dart VM or server, initialize Jaspr before converting:

void main() {
  Jaspr.initializeApp();
}

Quick Start #

import 'package:jaspr/dom.dart';
import 'package:jaspr/server.dart';
import 'package:jaspr_converter/jaspr_converter.dart';

Future<void> main() async {
  Jaspr.initializeApp();

  final component = div(classes: 'card', [
    h1([Component.text('Hello')]),
    p([Component.text('Generated from Jaspr')]),
  ]);

  final html = await JasprConverter.toHtml(component);

  print(html);
}

Example output:

<body>
  <div class="card">
    <h1>Hello</h1>
    <p>Generated from Jaspr</p>
  </div>
</body>

Newsletter and Email Rendering #

jaspr_converter can be used to render email templates and newsletters built with Jaspr components to HTML for delivery through email providers like SendGrid, Mailgun, Postmark, AWS SES, or your own email pipeline.

This is useful when newsletter content is dynamic. You can fetch data in an AsyncBuilder, compose the email layout with Jaspr components, and call toHtmlSync(true) in server-side code to produce a full HTML document.

import 'dart:io';

import 'package:jaspr/dom.dart';
import 'package:jaspr/server.dart';
import 'package:jaspr_converter/jaspr_converter.dart';

Future<void> main() async {
  Jaspr.initializeApp();

  final newsletter = AsyncBuilder(
    builder: (context) async {
      final posts = await loadLatestPosts();

      return Component.element(
        tag: 'table',
        attributes: {
          'role': 'presentation',
          'width': '100%',
          'cellpadding': '0',
          'cellspacing': '0',
          'style':
              'max-width: 640px; margin: 0 auto; font-family: Arial, sans-serif;',
        },
        children: [
          Component.element(
            tag: 'tbody',
            children: [
              Component.element(
                tag: 'tr',
                children: [
                  Component.element(
                    tag: 'td',
                    attributes: {
                      'style':
                          'padding: 24px; background: #101828; color: white;',
                    },
                    children: [
                      h1([Component.text('Weekly Product Digest')]),
                      p([Component.text('Generated with Jaspr components.')]),
                    ],
                  ),
                ],
              ),
              for (final post in posts)
                Component.element(
                  tag: 'tr',
                  children: [
                    Component.element(
                      tag: 'td',
                      attributes: {
                        'style':
                            'padding: 20px 24px; border-bottom: 1px solid #eaecf0;',
                      },
                      children: [
                        h2([Component.text(post.title)]),
                        p([Component.text(post.summary)]),
                        a(href: post.url, [Component.text('Read more')]),
                      ],
                    ),
                  ],
                ),
            ],
          ),
        ],
      );
    },
  );

  final html = await newsletter.toHtmlSync(true);
  await File('newsletter-email.html').writeAsString(html);
}

Email clients have stricter rendering behavior than browsers, so table-based layouts and inline styles are usually safer for production newsletters. The converter gives you the HTML output, while your email provider handles delivery.

Public APIs #

JasprConverter.toHtml #

Converts a Jaspr Component into HTML markup.

final html = await JasprConverter.toHtml(
  div(classes: 'card', [
    h1([Component.text('Hello')]),
    p([Component.text('World')]),
  ]),
);

Signature:

static Future<String?> toHtml(
  Component component, {
  bool fullHtmlDocument = false,
  String? outputFilename,
  String? pageTitle,
})

Parameters:

Parameter Description
component The Jaspr component tree to render.
fullHtmlDocument When false, returns a rendered fragment/body-level result. When true, returns a complete HTML document.
outputFilename Optional filename or path where the HTML should be saved.
pageTitle Optional document title used when a full document is generated.

Generate a full HTML document:

final document = await JasprConverter.toHtml(
  main_([
    h1([Component.text('Docs')]),
    p([Component.text('Full document output')]),
  ]),
  fullHtmlDocument: true,
  pageTitle: 'Docs Page',
);

Save the generated HTML:

await JasprConverter.toHtml(
  myComponent,
  fullHtmlDocument: true,
  outputFilename: 'build/page.html',
  pageTitle: 'Generated Page',
);

Persistence behavior:

  • In the browser, outputFilename triggers a download.
  • On the Dart VM or server, outputFilename writes to the local filesystem.

JasprConverter.toComponent #

Converts HTML into a Jaspr Component.

final component = await JasprConverter.toComponent(
  '<section id="hero"><p>Hello</p></section>',
);

Signature:

static Future<Component?> toComponent(
  String source, {
  bool asStatefulComponent = false,
  bool fullHtmlDocument = false,
  String? outputFilename,
  String className = 'ConvertedComponent',
})

Parameters:

Parameter Description
source Raw HTML, a remote URL, a local file path, or a file:// URI.
asStatefulComponent Generates a StatefulComponent source file when true; otherwise generates a StatelessComponent.
fullHtmlDocument Preserves document-level structure when true.
outputFilename Optional filename or path where generated Dart source should be saved.
className Class name used when generated Dart source is written.

Supported sources:

// Raw HTML
final fromRawHtml = await JasprConverter.toComponent(
  '<main><h1>Hello</h1></main>',
);

// Remote URL
final fromUrl = await JasprConverter.toComponent(
  'https://example.com',
);

// Local file path on dart:io platforms
final fromFile = await JasprConverter.toComponent(
  'templates/home.html',
);

// Local file URI on dart:io platforms
final fromFileUri = await JasprConverter.toComponent(
  'file:///tmp/home.html',
);

Generate a Dart component file from HTML:

await JasprConverter.toComponent(
  '<section><h2>Hello</h2><p>Generated component</p></section>',
  outputFilename: 'lib/generated/converted_component.dart',
  className: 'ConvertedComponent',
);

Generate a stateful component:

await JasprConverter.toComponent(
  '<button>Click me</button>',
  outputFilename: 'lib/generated/action_button.dart',
  className: 'ActionButton',
  asStatefulComponent: true,
);

Component Extensions #

Importing package:jaspr_converter/jaspr_converter.dart also adds extension helpers to every Jaspr Component.

component.stringify #

Returns a Dart-style Jaspr component expression.

final component = div(classes: 'card', [
  h1([Component.text('Hello')]),
]);

final source = component.stringify;

print(source);

Example output:

div(
  classes: "card",
  [
    h1([Component.text('Hello')]),
  ]
)

This is useful when inspecting a component tree or generating component source manually. Runtime behavior such as callbacks and event handlers is not serialized.

component.toHtml([fullHtml]) #

Synchronously converts stateless and stateful component trees to HTML using the package serializer.

final html = div(classes: 'card', [
  h1([Component.text('Hello')]),
  p([Component.text('World')]),
]).toHtml();

Pass true to generate a complete HTML document:

final document = myComponent.toHtml(true);

await component.toHtmlSync([fullHtml]) #

Converts AsyncStatelessComponent instances to HTML on server-side dart:io platforms by awaiting their async build result. This is the preferred helper for dynamic newsletter and email templates that fetch content before rendering.

final html = await AsyncBuilder(
  builder: (context) async {
    return div([
      p([Component.text('Loaded asynchronously')]),
    ]);
  },
).toHtmlSync();

For non-async components, toHtmlSync returns the same result as component.toHtml(...).

Formatting #

Generated HTML is formatted for readability:

  • Root fragments are not padded with unnecessary leading spaces.
  • Text-only elements are kept compact, for example <h1>Hello</h1>.
  • Nested structural elements are indented on separate lines.
  • Full HTML documents include <!DOCTYPE html>, <html>, <head>, and <body> when requested.

Generated Dart source is also formatted to keep simple text children compact while preserving multi-line structure for larger component trees.

Example Project #

The package includes a runnable example with its own pubspec.yaml:

cd example
dart pub get
dart run jaspr_converter_example.dart

The example demonstrates component rendering, generated files, raw HTML parsing, local file parsing, extension helpers, and an async newsletter rendered to output/newsletter-email.html.

Limitations #

  • The converter focuses on HTML structure and static attributes.
  • Event handlers, closures, component state, and runtime behavior are not serialized into HTML or generated Dart source.
  • URL loading depends on the runtime environment and network access.
  • Local file paths and file:// URIs are only supported on dart:io platforms.
  • Async component rendering through toHtmlSync is server-side only.

Issues and Contributions #

If you encounter a bug or have a feature request, file an issue on the GitHub issue tracker. Contributions are welcome.

1
likes
160
points
19
downloads

Documentation

API reference

Publisher

verified publisherflutterful.dev

Weekly Downloads

Convert Jaspr component trees to HTML and parse HTML back into Jaspr components.

Repository (GitHub)
View/report issues

Topics

#jaspr #html #parser #generator

License

MIT (license)

Dependencies

html, http, jaspr, universal_web

More

Packages that depend on jaspr_converter