Jaspr Framework Dev
Core Principles
1. Execution Model
- •Server-Side Rendering (SSR): Preferred for SEO and initial load. Global config in
lib/main.server.dart. - •Client-Side Hydration: Use
@clientfor stateful/interactive components. - •Isomorphic Code: Favor
package:jaspr/jaspr.dartfor core logic andpackage:jaspr/dom.dartfor HTML elements.
2. Content Management (jaspr_content)
- •Eager Loading: Enable
eagerlyLoadAllPages: trueinContentAppto access metadata for all pages. - •Programmatic Access: If
ContentContext.of(context).pagesis inaccessible, manually read thecontent/directory usingDirectory('content/blog').listSync()and parse Markdown files. - •Frontmatter Parsing: When manually parsing, split content by
---and extract keys liketitle:,date:, anddescription:. - •Frontmatter Access in Layouts: Inside a custom
PageLayout, access frontmatter viapage.data.page['your_key']. - •Custom Slugs/Routing: To decouple filenames from URL paths (e.g.,
2024-01-01-post.md->/blog/post), useContentApp.customand provide arouterBuilder. InsiderouterBuilder, iterate through the generated routes and return a newRoutewith the desired path by reading the file's frontmatter.
3. Custom Layouts
- •Implementation: Extend
PageLayoutorPageLayoutBase.PageLayoutBaseprovides defaultbuildHeadlogic for SEO tags. - •Member Implementation: If extending
PageLayout, implementbuildLayout(Page page, Component child). If extendingPageLayoutBase, implementbuildBody(Page page, Component child). - •Layout Styling: To include layout-specific global styles, override
buildHeadand yield aStylecomponent:yield Style(styles: _styles);. - •DocsLayout Limitations:
DocsLayoutdoes not have built-in flags to hide the title/description. Use a custom layout for full control over thecontent-header. - •Header Navigation: The
Headercomponent fromjaspr_contentaccepts anitemslist of components, ideal for top-level navigation links. - •DOM Naming: Use
main_()for the<main>tag to avoid name collisions with the Dartmain()function.
4. Styling (CSS-in-Dart)
- •Typed API Enums:
- •
Display.flex,Display.grid,Display.none. - •
AlignItems.start,AlignItems.center,AlignItems.end. - •
FlexDirection.row,FlexDirection.column. - •
FontWeight.w400(normal),FontWeight.w600(semibold),FontWeight.w700(bold),FontWeight.w800(extrabold).
- •
- •Units & Spacing: Use extensions like
.rem,.px,.percent, orUnit.auto. For.all(Unit.zero), useUnit.zeroinstead of0. - •Raw Styles: Use
raw: {}for:- •
grid-template-columns: 'repeat(auto-fit, minmax(420px, 1fr))'. - •
gap: '3rem'(ifGap()constructor fails). - •
aspect-ratio: '2 / 1',object-fit: 'cover'. - •
border: '1px solid rgba(0, 0, 0, 0.2)'. - •
text-decoration: 'underline'.
- •
Workflows
Searching Documentation
- •ALWAYS use the
context7MCP server as the primary source for documentation, code examples, and API references for Jaspr and related libraries. - •Call
resolve-library-idwithjasprto get the correct library ID:/schultek/jaspr. Note: This ID also contains documentation for sub-packages likejaspr_content,jaspr_router, etc. - •Use
query-docswith/schultek/jasprto find specific information before attempting to write code or solve complex framework-specific issues.
Creating a Blog Overview
- •Create a component that accesses all loaded pages using
context.pages(requireseagerlyLoadAllPages: trueinContentApp). - •Filter pages by path (e.g.,
page.path.startsWith('blog/')) and ensure they aren't index pages. - •Access frontmatter data via
page.data.page['key'](e.g.,title,description,date). - •Sort posts by
date(parsed from frontmatter) descending. - •Render using a
ulwithDisplay.gridandauto-fitfor responsiveness.
Registering Custom Components
Use CustomComponent in ContentApp to enable custom tags in Markdown:
dart
CustomComponent(
pattern: 'MyComponent',
builder: (name, attributes, child) => MyComponent(
title: attributes['title'],
children: [if (child != null) child],
),
)
AFTER making code changes and BEFORE considering a task complete, you MUST:
- •Build: Run
jaspr buildand verify successful completion.
No-Shortcut Policy
- •Never skip the build: Even for "trivial" or "safe" changes (like paths, text, or CSS), a build is required to ensure no regressions or syntax errors were introduced.
- •Final Tool Call: The last tool call in any turn that modifies the codebase or assets MUST be
jaspr build(or a command that includes it).
Pre-Response Check
Before sending a text response to the user after a modification:
- •"Did I run
jaspr buildin this turn?" - •If NO, run it now.
- •If YES but it failed, resolve the error.
Common Issues
- •highlighter crash:
CodeBlock()fromjaspr_contentmay throw "Null check operator used on a null value" due to complex language hints or missing theme colors. Disable it inlib/main.server.dartif it blocks the build. - •OptionsSkew: If
jaspr buildfails withOptionsSkew, runpkill -f dart && pkill -f jasprand try again. - •Import Errors: Ensure
package:jaspr/dom.dartis used for HTML tags andpackage:jaspr/jaspr.dartfor core components.