jaspr_converter 1.1.0
jaspr_converter: ^1.1.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
Componenttree 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
.htmland.dartoutput. - 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(fullHtml: 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,
outputFilenametriggers a download. - On the Dart VM or server,
outputFilenamewrites 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 ondart:ioplatforms. - Async component rendering through
toHtmlSyncis 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.