Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
9b4960f
Initial import of flutter/website-cms into repository
parlough May 12, 2026
fe8f17a
Add sites/www to pub workspace
parlough May 12, 2026
c3cbb85
Add support for the site from the dash_site tool
parlough May 12, 2026
7bb243a
Set up building, serving, and cleaning in dash_site tool
parlough May 12, 2026
03672b6
Fix image asset loading and transformation issues
parlough May 12, 2026
531a113
Set up and separate GitHub actions workflows
parlough May 12, 2026
0fd5cb7
Use combined stage and deploy setup
parlough May 13, 2026
092f5cf
Adjust root AGENTS.md file
parlough May 13, 2026
65b8b47
Update workflow display name
parlough May 13, 2026
9de68e2
Enable serving both sites at the same time
parlough May 13, 2026
f0a3460
Avoid losing the firebase deploy output
parlough May 14, 2026
e7cc2a3
Update deploy and stage to rely on separate triggers
parlough May 14, 2026
c1ef951
Move stage and deploy logic to Dart for easier maintainence
parlough May 14, 2026
307a190
Fix and simplify _SITE substitution
parlough May 14, 2026
bf82133
Hook up different Firebase emulator ports per site
parlough May 14, 2026
3552dee
Clean up wording of PR comments
parlough May 14, 2026
e76efef
Adjust workflow group name for marketing site
parlough May 14, 2026
ccc5fae
Rename dart test workflows
parlough May 14, 2026
8be0955
Fix conditional running of dart test workflow
parlough May 14, 2026
ea0c449
Update dash_site test-dart command to run site-specific tests
parlough May 14, 2026
ad98f4f
Remove strange tracking state
parlough May 14, 2026
152adca
Clean up comments on stage-preview command
parlough May 14, 2026
ab04803
Merge branch 'main' into feat/merge-website-cms
parlough May 21, 2026
5fc6c00
Keep deploy image the same for now
parlough May 21, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
70 changes: 70 additions & 0 deletions .github/workflows/www.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
name: Marketing site

on:
push:
branches:
- main
paths:
- 'sites/www/**'
- 'tool/dash_site/**'
- 'tool/config/linkcheck-skip-list.txt'
- 'pubspec.yaml'
- 'pubspec.lock'
- 'analysis_options.yaml'
- '.github/workflows/www.yml'
pull_request:
branches:
- main
paths:
- 'sites/www/**'
- 'tool/dash_site/**'
- 'tool/config/linkcheck-skip-list.txt'
- 'pubspec.yaml'
- 'pubspec.lock'
- 'analysis_options.yaml'
- '.github/workflows/www.yml'
schedule:
- cron: '0 0 * * 0'

permissions: read-all

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}

jobs:
linkcheck:
name: Build and check links
runs-on: ubuntu-latest
if: github.repository == 'flutter/website'
timeout-minutes: 30
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
- uses: dart-lang/setup-dart@65eb853c7ba17dde3be364c3d2858773e7144260
with:
sdk: beta
- name: Fetch Dart dependencies
run: dart pub get
- name: Install firebase-tools
run: curl -sL https://firebase.tools | bash
- name: Build site
run: dart run dash_site --site=www build
- name: Check for broken Markdown link references
run: dart run dash_site --site=www check-link-references
- name: Check for broken internal links
run: dart run dash_site --site=www check-links

firebase-validate:
name: Validate Firebase configuration
runs-on: ubuntu-latest
if: github.repository == 'flutter/website'
timeout-minutes: 10
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
- uses: dart-lang/setup-dart@65eb853c7ba17dde3be364c3d2858773e7144260
with:
sdk: beta
- name: Fetch Dart dependencies
run: dart pub get
- name: Validate the firebase.json file
run: dart run dash_site --site=www verify-firebase-json
41 changes: 29 additions & 12 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,20 @@ content and code in this repository.
## Project overview

This repository contains the source code and content for
the Flutter framework's documentation website.
It is hosted at `docs.flutter.dev` and shouldn't be confused with
the marketing site at `flutter.dev` or the API docs at `api.flutter.dev`.
the Flutter framework's documentation and marketing websites:

The website is statically built and implemented with
- `docs.flutter.dev`:
The Flutter framework's documentation website.
- `flutter.dev`:
Flutter's homepage and marketing website.

The API docs at `api.flutter.dev` are embedded in the Flutter SDK source
and are maintained in the <https://github.com/flutter/flutter> repository.

The websites are statically built and implemented with
Dart and the [Jaspr](https://jaspr.site) web framework.
For loading content, data, and some of its assets,
it uses [Jaspr Content](https://docs.jaspr.site/content).
For loading content, data, and some assets,
they use [Jaspr Content](https://docs.jaspr.site/content).

### Directory structure

Expand All @@ -30,29 +36,40 @@ it uses [Jaspr Content](https://docs.jaspr.site/content).
for the sidenav, glossary, and various indices.
- `sites/docs/src/_includes/`:
Liquid partial files written in Markdown.
- `sites/www/`:
The implementation of flutter.dev,
written in Dart using Jaspr and Jaspr Content.
- `sites/www/content/`:
Markdown-based marketing pages and structured content.
- `sites/www/lib/`:
Dart source code for the site.
- `sites/www/firebase.json`:
Firebase Hosting configuration for flutter.dev.
- `examples/`:
A pub workspace containing Dart and Flutter code examples,
referenced by code excerpts in the Markdown files.
referenced by code excerpts in the docs Markdown files.
- `tool/dash_site/`:
CLI tool for site development and maintenance.

## Common commands

While working on the site,
While working on these sites,
you might need to run these commands:

```bash
# Install or update Dart dependencies:
dart pub get

# Serve a dev server of the site locally:
dart run dash_site serve
dart run dash_site --site=docs serve
dart run dash_site --site=www serve

# Build a production version of the site:
dart run dash_site build
dart run dash_site --site=docs build
dart run dash_site --site=www build

# Sync code excerpts to Markdown files:
dart run dash_site refresh-excerpts
# Sync docs code excerpts to Markdown files:
dart run dash_site --site=docs refresh-excerpts

# Learn what other commands are available:
dart run dash_site --help
Expand Down
5 changes: 2 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -148,9 +148,8 @@ following the instructions in [Get the prerequisites](#get-the-prerequisites).
This command generates and serves the site on a
local port that's printed to your terminal.

5. View your changes in the browser by navigating to <http://localhost:8080>.

Note the port might be different if `8080` is taken.
5. View your changes in the browser by navigating to
the local URL printed to your terminal.

6. Make your changes to the local repo.

Expand Down
1 change: 1 addition & 0 deletions pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ workspace:
- packages/analysis_defaults
- packages/excerpter
- sites/docs
- sites/www
- tool/dash_site
117 changes: 117 additions & 0 deletions sites/www/.agents/rules/jaspr.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
---
trigger: always_on
---

# Jaspr Project Rules

## Core Principles
- **Framework**: Use [Jaspr](https://github.com/schultek/jaspr) for all web UI components. Do not use standard Flutter widgets (Container, Column, Row, etc.).
- **Elements**: Use HTML-like components provided by Jaspr (`div`, `section`, `h1`, `p`, `img`, `a`, `button`, `span`, etc.).

## Components
- **Stateless vs Stateful**:
- Use `StatelessComponent` for purely presentational components that do not manage local state.
- Use `StatefulComponent` only when internal state management (e.g., animations, form input handling) is required.
- **Client-Side Rendering**: Annotate components with `@client` if they require browser-specific APIs or interactivity that cannot be server-side rendered (SSR).

## Project Structure
- **Components**: Place reusable UI components in `lib/components/`.
- **Pages**: Place route-level components in `lib/pages/`.

## Common Patterns
- **Lists**: Prefer Dart collection-for and collection-if elements over`.map().toList()` to render lists of children.
- **Conditionals**: Prefer Dart `if` inside the children list over ternary operators for conditional rendering.

## Best Practices

When writing Jaspr components, adhere to these modern syntax rules:

### Component Signature
Always use the `Component build(BuildContext context)` signature (not `Iterable<Component>` with `yield`).

```dart
// ✅ Correct
@override
Component build(BuildContext context) {
return div([...]);
}

// ❌ Avoid
@override
Iterable<Component> build(BuildContext context) sync* {
yield div([...]);
}
```

### Text Components
Use the dot-shorthand `.text()` for adding text nodes, which is cleaner than wrapping strings in `text()`.

```dart
// ✅ Correct
div([
.text('Hello World'),
])

// ❌ Avoid, Deprecated
div([
text('Hello World'),
])
```

### Links and Navigation

Prefer standard `a` tags over `Link` components when you need full control over attributes or are migrating strict HTML.

```dart
// ✅ Correct
a(
href: '/path',
classes: 'my-link',
events: {'click': (e) => ...}, // Easy to attach events
[.text('Go')]
)
```

### Positional Arguments for Children

`div`, `span`, and other container components typically take children as a positional `List<Component>`.

```dart
// ✅ Correct
div(classes: 'wrapper', [
child1,
child2
])

// ❌ Avoid
div(classes: 'wrapper', children: [ ... ])
```

- Use `main_([...])` for rendering a `<main>` element.
- Use `Component.element(tag: 'xx', children: [...])` for an element that does not have a direct component.

### Using Browser APIs and handling Global/Window Events

Use `import 'package:universal_web/web.dart' as web;` for accessing standard browser APIs (e.g. `window` or `window.document`) when implementing browser-specific logic (location checking, scroll locking).

Use `web.EventStreamProviders` to listen to window-level events in `initState` and cancel stream subscriptions in `dispose`.

```dart
StreamSubscription? _resizeSubscription;

@override
void initState() {
super.initState();
if (kIsWeb) {
_resizeSubscription = web.EventStreamProviders.resizeEvent
.forTarget(web.window)
.listen((_) => setState(() {}));
}
}

@override
void dispose() {
_resizeSubscription?.cancel();
super.dispose();
}
```
Loading
Loading