server library
Server-side half of esen_seo: bot detection and semantic HTML delivery for a shelf server.
Pure Dart without any Flutter imports — runs with dart run, in
Docker or on any Dart-capable host. Bots get real semantic HTML
straight in the page source, real users get the Flutter web app:
import 'package:esen_seo/server.dart';
import 'package:shelf/shelf.dart';
import 'package:shelf/shelf_io.dart' as io;
import '../lib/seo_routes.dart'; // dieselbe Tabelle wie die App
void main() async {
final handler = const Pipeline()
.addMiddleware(seoBotMiddleware(
routes: seoRoutes,
siteBase: 'https://example.com',
))
.addHandler(flutterAppHandler);
await io.serve(handler, 'localhost', 8080);
}
SeoMeta, SeoSchema, SeoNode, SeoRoute and HtmlRenderer are shared with the Flutter side, so head and body render identically in both worlds.
Classes
- BotDetector
- Detects crawlers and preview bots by their User-Agent header.
- HtmlRenderer
- Renders a tree of SeoNodes into a clean, semantic HTML string.
- OpenGraphMeta
- OpenGraph values for link previews (Facebook, LinkedIn, WhatsApp, …).
- SeoAuditPolicy
- What the audit considers a problem.
- SeoAuditReport
- The result of one audit run.
- SeoCollectionAction
- Closed action vocabulary understood by both presentations.
- SeoCollectionNextPage
- SeoCollectionPreviousPage
- SeoCollectionRecord
- Prepared pure data needed to select and order one collection entry.
- SeoCollectionSelectCategory
- SeoCollectionSetPage
- SeoCollectionSetQuery
- SeoCollectionSetSort
- SeoCollectionSnapshot
- Result of applying SeoCollectionState to a complete data set.
- SeoCollectionState
- Immutable interaction state for one collection.
- SeoCollectionUrlCodec
- Maps one collection's closed state to namespaced query parameters.
- SeoDirectoryRuntimeStore
-
Loads
<id>.jsonand<id>.jsfrom a build-owned directory. - SeoDocument
- One page, produced by one read: metadata and body together, so they can never describe different records.
- SeoDomFirstApplicationRuntime
- One application runtime selected by a DOM-first route.
- SeoDomFirstRuntimeArtifact
- JavaScript that passed manifest, identity, size, and content verification.
- SeoDomFirstRuntimeManifest
- Describes one compiled and content-addressed application runtime.
- SeoDomFirstRuntimeStore
- Loads verified application runtimes for server and prerender delivery.
- SeoDomFirstTabsApplicationRuntime
- An application-authored transition executed by the tabs adapter.
- SeoFinding
- One problem, on one page.
- SeoMeta
-
Page metadata for the document
<head>: title, description, OpenGraph and Twitter Card tags. - SeoNode
- A node in the semantic HTML tree that mirrors the Flutter widget tree.
- SeoPage
- A complete server-rendered page: head metadata plus a semantic HTML body.
- SeoRedirect
- A redirect from one URL to another — the target a SeoDocument has no field for.
- SeoRequest
- What a resolver is asked for.
- SeoResolution
- What a route resolves to for one concrete URL: either a page (SeoDocument) or a redirect (SeoRedirect).
- SeoResolvedPage
- One concrete URL of the site, resolved exactly once.
- SeoRichTextSpan
- One span in a declarative rich-text tree.
- SeoRoute
- One entry in the SEO route table — the single source of truth for a page's URL, metadata and (server-side) body.
- SeoRouteMatch
- A successful lookup in the route table.
- SeoSchema
- A Schema.org JSON-LD block for rich search results.
- SeoTabsAction
- A user intent understood by the shared tabs transition.
- SeoTabsFirst
- Selects the first tab.
- SeoTabsLast
- Selects the last tab.
- SeoTabsNext
- Selects the next tab, wrapping from the last tab to the first.
- SeoTabsPrevious
- Selects the previous tab, wrapping from the first tab to the last.
- SeoTabsSelect
- Selects one tab by index. Out-of-range indices leave selection unchanged.
- SeoTabsState
- The complete state needed to select one panel in a tab group.
- SeoThemeAction
- A closed action understood by both Flutter and DOM-first presentations.
- SeoThemePersistEffect
- The only external effect emitted by transitionSeoTheme.
- SeoThemeRestoreAction
- Restore a persisted preference, or system mode when no preference exists.
- SeoThemeState
- Current theme state, including the platform preference used by system mode.
- SeoThemeSystemBrightnessAction
- Update the platform brightness used while the preference is system.
- SeoThemeToggleAction
- Toggle away from the currently resolved brightness.
- SeoThemeTransitionResult
- Next state plus an optional declarative persistence request.
- TwitterCardMeta
- Twitter Card values. Title, description and image come from the OpenGraph tags — Twitter reads those automatically.
Enums
- SeoCollectionSort
- Sort modes supported by the closed collection interaction contract.
- SeoDetail
- How much of a page the caller needs.
- SeoDomFirstFeature
- Package-owned behaviour a DOM-first route explicitly opts into.
- SeoMotionPreset
- Closed, package-owned motion choices for bridge components.
- SeoRedirectScope
- Who a resolver-issued SeoRedirect is honoured for.
- SeoRenderMode
- How the semantic HTML tree is presented in the browser.
- SeoRenderTarget
- Where a rendered fragment is going to land.
- SeoRichTextRole
- Semantic roles supported by SeoRichTextSpan.
- SeoRouteDelivery
- Which web presentation owns a route.
- SeoSeverity
- How much a finding matters.
- SeoThemePreference
- The persisted presentation preference.
Extension Types
- SeoCheck
-
The identity of a check, e.g.
title.missing.
Constants
- seoAutoInfrastructureCacheTtl → const Duration
-
The default for
seoBotMiddleware(infrastructureCacheTtl:): derive each infrastructure file's cache lifetime from what it actually reads, rather than from one flag for the whole table. - seoCollectionMaxCategories → const int
- Largest category set the progressive adapter will enhance.
- seoCollectionMaxItems → const int
- Largest collection the progressive adapter will enhance.
- seoCollectionMaxSearchLength → const int
- Largest normalized search corpus accepted for one enhanced item.
- seoCollectionMaxSortKey → const int
- Largest exactly representable integer shared by Dart VM and JavaScript.
- seoDefaultStylesheet → const String
- A minimal classless stylesheet so semantic HTML looks presentable without any work — the visual counterpart to the smart defaults. Used by default for DOM-first pages and available for SeoRenderMode.visibleShell. In the invisible default mode there is nothing to style.
- seoDomFirstApplicationScriptAttribute → const String
- Marks a verified application-authored runtime in a DOM-first document.
- seoDomFirstAttribute → const String
- Marks a semantic container that permanently owns the browser route.
- seoDomFirstBootstrapScriptAttribute → const String
- Marks the pre-paint theme restoration script in a generated document.
- seoDomFirstCollectionStylesheet → const String
- Structural styles for the compiled DOM-first collection control.
- seoDomFirstRuntimeManifestSchema → const int
- Current on-disk format of an application DOM-first runtime manifest.
- seoDomFirstRuntimeMaxBytes → const int
- Maximum accepted application runtime size before compression.
- seoDomFirstRuntimeMaxGzipBytes → const int
- Maximum accepted application runtime size after level-9 gzip compression.
- seoDomFirstScriptAttribute → const String
- Marks the package-owned DOM-first runtime in a generated document.
- seoDomFirstTabsStylesheet → const String
- Structural styles for the compiled DOM-first tabs control.
- seoDomFirstThemeToggleStylesheet → const String
- Self-contained styling for the package-owned theme toggle control.
- seoInteractionRuntime → const String
- Package-owned JavaScript that progressively enhances marked components in the package's visible semantic container.
- seoInteractionScriptAttribute → const String
- Marks the package-owned interaction runtime in a generated document.
- seoInteractionStylesheet → const String
- Structural styles for controls created by seoInteractionRuntime.
- Maximum supported nesting depth for a navigation tree.
-
seoPieChartDefaultPaletteArgb
→ const List<
int> - Default ARGB palette used by buildSeoPieChartNodes.
- seoRichTextMaxDepth → const int
- Maximum supported nesting depth for a rich-text span tree.
- seoThemePreferenceStorageKey → const String
- The storage key shared by the early bootstrap and browser adapter.
- seoThemeToggleCompactBreakpoint → const int
- Viewport width at which an opted-in theme toggle becomes icon-only.
Properties
- seoMotionStylesheet → String
-
Motion rules for components carrying a supported fixed package marker.
final
Functions
-
applySeoTabsTransition(
SeoTabsTransition transition, SeoTabsState state, SeoTabsAction action) → SeoTabsState -
Executes
transitionwithin the closed state contract of a tabs control. -
assertSeoHealthy(
SeoAuditReport report, {SeoSeverity threshold = SeoSeverity.error}) → void -
Throws SeoAuditFailure unless
reportpasses atthreshold. -
auditSeoPages(
{required List< SeoResolvedPage> pages, required List<SeoRoute> routes, required String siteBase, SeoAuditPolicy policy = const SeoAuditPolicy(), Map<String, Object> resolverFailures = const {}}) → SeoAuditReport - Audits an already-resolved set of pages.
-
auditSeoRoutes(
{required List< SeoRoute> routes, required String siteBase, List<String> additionalPaths = const [], SeoAuditPolicy policy = const SeoAuditPolicy()}) → Future<SeoAuditReport> - Audits a route table for the mistakes the package cannot prevent.
-
boundSeoCollectionQuery(
String input) → String - Bounds user-entered query state before either presentation evaluates it.
-
buildSeoBarChartNodes(
{required List< SeoBarChartComponentEntry> data, String? title, double height = 220, int colorArgb = 0xFF2563EB, SeoMotionPreset motion = SeoMotionPreset.none}) → List<SeoNode> - Builds the semantic mirror nodes for a bar chart.
-
buildSeoBreadcrumbsNodes(
{required List< SeoBreadcrumbComponentEntry> items, String separator = '/', String label = 'Breadcrumb'}) → List<SeoNode> - Builds the semantic mirror nodes for a breadcrumb trail.
-
buildSeoCarouselNodes(
{required List< SeoCarouselComponentEntry> slides, int headingLevel = 3, String? interactionId, String interactionLabel = 'Carousel', String previousLabel = 'Previous slide', String nextLabel = 'Next slide', int initialIndex = 0}) → List<SeoNode> - Builds the semantic mirror nodes for a complete carousel.
-
buildSeoCollectionNodes(
{required List< SeoCollectionComponentEntry> items, String? interactionId, String interactionLabel = 'Collection', int pageSize = 12, SeoCollectionSort initialSort = SeoCollectionSort.newest, String searchLabel = 'Search', String categoriesLabel = 'Categories', String allCategoriesLabel = 'All', String sortLabel = 'Sort', String newestLabel = 'Newest', String oldestLabel = 'Oldest', String titleLabel = 'Title', String previousLabel = 'Previous', String nextLabel = 'Next', String resultsLabel = 'results', String noResultsLabel = 'No results', String pageLabel = 'Page', bool synchronizeUrl = false}) → List<SeoNode> - Builds a complete collection that can be progressively searched and paged.
-
buildSeoDataTableNodes(
{required List< String> columns, required List<List< rows, String? title}) → List<String> >SeoNode> - Builds the semantic mirror nodes for a data table.
-
buildSeoFaqNodes(
{required List< SeoFaqComponentEntry> entries, String? title, int titleLevel = 2}) → List<SeoNode> - Builds the semantic mirror nodes for an FAQ section.
-
buildSeoFigureNodes(
{required String src, required String alt, String? caption, int? width, int? height, bool lazy = false}) → List< SeoNode> - Builds the semantic mirror nodes for an image figure.
-
buildSeoListViewNodes<
T> ({required List< T> items, required List<SeoNode> nodeBuilder(T item, int index), String listTag = 'div', String? itemTag, Map<String, String> attributes = const {}}) → List<SeoNode> - Builds the semantic mirror nodes for a complete, possibly lazy list.
- Builds the semantic mirror nodes for a complete navigation tree.
-
buildSeoPieChartNodes(
{required List< SeoPieChartComponentEntry> data, String? title, double diameter = 180, List<int> paletteArgb = seoPieChartDefaultPaletteArgb}) → List<SeoNode> - Builds the semantic mirror nodes for a pie chart.
-
buildSeoRatingNodes(
{required double value, int max = 5, String? label}) → List< SeoNode> - Builds the semantic mirror nodes for a rating.
-
buildSeoRichTextNodes(
{required List< SeoRichTextSpan> spans, String tag = 'p', Map<String, String> attributes = const {}}) → List<SeoNode> - Builds semantic HTML nodes for a rich-text tree.
-
buildSeoStepperNodes(
{required List< SeoCarouselComponentEntry> steps, int headingLevel = 3, String? interactionId, String interactionLabel = 'Steps', String previousLabel = 'Back', String nextLabel = 'Next', String positionLabel = 'Step', int initialIndex = 0}) → List<SeoNode> - Builds the complete ordered semantic source for a stepper.
-
buildSeoTabsNodes(
{required List< SeoCarouselComponentEntry> tabs, int headingLevel = 3, String? interactionId, String interactionLabel = 'Tabs', int initialIndex = 0}) → List<SeoNode> - Builds the semantic mirror nodes for a tab group.
-
buildSeoTestimonialNodes(
{required String quote, String? author, String? role, String? sourceUrl}) → List< SeoNode> - Builds the semantic mirror nodes for a testimonial.
-
buildSeoThemeToggleNodes(
{String lightLabel = 'Light', String darkLabel = 'Dark', String lightSemanticLabel = 'Use light theme', String darkSemanticLabel = 'Use dark theme', bool compactOnSmallScreens = false}) → List< SeoNode> - Builds the inert marker upgraded by the package-owned theme runtime.
-
cssColorArgb(
int argb) → String - Formats an ARGB integer as lowercase CSS hexadecimal.
-
cssNumber(
double value) → String - Formats a finite CSS number without an unnecessary decimal suffix.
-
cssPercent(
double value, double total) → String -
Formats
value's share oftotalas a percentage with one decimal at most. -
finishSeoResolution(
SeoResolution resolution, {required String path, String? canonicalBase, void onWarning(String path, String warning)?}) → SeoResolution - The chokepoint. Every path from a resolver to any output — SSR, prerender, sitemap.xml, llms.txt — runs its resolution through here, exactly as every tag and attribute runs through the renderer's policy. A resolver is a new road from (eventually CMS) data into HTTP output, and the mistake this package already made once was to put a policy in one output path while another bypassed it.
-
initialSeoTabsState(
{required int count, int index = 0}) → SeoTabsState -
Returns a valid initial state for
counttabs. -
isValidSeoApplicationRuntimeId(
String id) → bool -
Whether
idis safe as a logical identity and artifact file component. -
isValidSeoCollectionSortKey(
int sortKey) → bool -
Whether
sortKeyhas identical integer semantics on VM and JavaScript. -
isValidSeoInteractionId(
String value) → bool -
Whether
valueis safe to use as a package interaction identifier. -
loadSeoDomFirstRuntime(
SeoDomFirstRuntimeStore store, SeoDomFirstApplicationRuntime reference) → Future< SeoDomFirstRuntimeArtifact> - Loads a runtime and rejects stores that return a different identity.
-
matchSeoRoute(
List< SeoRoute> routes, String path) → SeoRouteMatch? -
Finds the first route in
routesmatchingpath, ornull. -
normalizeSeoCollectionPageSize(
int pageSize) → int - Keeps page sizes useful and bounds the amount shown in one DOM mutation.
-
normalizeSeoCollectionText(
String input) → String - Normalizes human text identically in Flutter and compiled JavaScript.
-
normalizeSeoPath(
String path) → String -
Normalizes a path: leading slash, no trailing slash,
''→/. -
pagesForGenerator(
{required String canonicalBase, List< SeoRoute> ? routes, List<SeoResolvedPage> ? pages, List<String> additionalPaths = const [], SeoDetail detail = SeoDetail.head}) → List<SeoResolvedPage> -
The shared front door of the synchronous generators
(seoSitemapXml, seoLlmsTxt): resolve
routes, or validate and return a pre-resolvedpagessnapshot. -
parseSeoCollectionSort(
String value) → SeoCollectionSort? - Parses a package-owned sort marker.
-
parseSeoThemePreference(
String? value) → SeoThemePreference - Parses the closed storage representation. Invalid values use system mode.
-
prerenderSite(
{required List< SeoRoute> routes, required String siteBase, String buildDir = 'build/web', List<String> additionalPaths = const [], bool writeSitemap = true, bool writeRobotsTxt = true, bool writeLlmsTxt = true, bool write404Page = true, String? indexNowKey, SeoRenderMode renderMode = SeoRenderMode.seoOnly, String? stylesheet, String? domFirstStylesheet = seoDefaultStylesheet, bool enableInteractions = false, String? interactionNonce, SeoDomFirstRuntimeStore? domFirstRuntimeStore, int concurrency = 8, void onSkipped(String path, SeoResolution resolution)?, void onError(String path, Object error, StackTrace stack)?}) → Future<List< String> > - Bakes the SEO route table into the built Flutter web app as static HTML files — for hosting without a Dart server (Firebase Hosting, GitHub Pages, any CDN).
-
resolveSeoPages(
{required List< SeoRoute> routes, String? canonicalBase, List<String> additionalPaths = const [], SeoDetail detail = SeoDetail.full, bool enumerateRoutePaths = true, int concurrency = 8, void onError(String path, Object error, StackTrace stack)?, void onWarning(String path, String warning)?, bool debugCheckMetaStability = false}) → Future<List< SeoResolvedPage> > - Enumerates every concrete URL the table stands for and resolves each one once, asynchronously.
-
resolveSeoPagesSync(
{required List< SeoRoute> routes, String? canonicalBase, List<String> additionalPaths = const [], SeoDetail detail = SeoDetail.head, bool enumerateRoutePaths = true}) → List<SeoResolvedPage> - The synchronous engine behind the sync generators (seoSitemapXml, seoLlmsTxt).
-
safeChartValue(
double value) → double - Normalizes chart input data so invalid and negative values become zero.
-
safeDimension(
double value, double fallback) → double - Normalizes a positive dimension, falling back for invalid input.
-
selectSeoCollection(
{required List< SeoCollectionRecord> records, required int categoryCount, required int pageSize, SeoCollectionState state = const SeoCollectionState()}) → SeoCollectionSnapshot -
Computes the canonical result for
statewithout mutatingrecords. -
seoBotMiddleware(
{List< SeoRoute> ? routes, SeoPageResolver? resolve, String? siteBase, bool serveSitemap = true, bool serveRobotsTxt = true, bool serveLlmsTxt = true, String? indexNowKey, List<String> additionalSitemapPaths = const [], bool unknownRoutesAs404 = true, BotDetector detector = const BotDetector(), SeoRedirectScope applyResolverRedirects = SeoRedirectScope.all, String? domFirstStylesheet = seoDefaultStylesheet, String? domFirstNonce(Request request)?, SeoDomFirstRuntimeStore? domFirstRuntimeStore, Duration? infrastructureCacheTtl = seoAutoInfrastructureCacheTtl, void onResolveError(String path, Object error, StackTrace stack)?}) → Middleware - Shelf middleware that serves semantic HTML to bots and passes real users through to the wrapped handler (usually the Flutter web build).
-
seoCollectionCategoryIndexes(
List< String> categories, List<String> categoryLabels) → List<int> -
Maps one entry's labels to the stable indexes from
categoryLabels. -
seoCollectionCategoryLabels(
Iterable< List< groups) → List<String> >String> - Derives stable display categories, deduplicated by normalized label.
-
seoCollectionSortMarker(
SeoCollectionSort sort) → String - Stable marker serialized into package-owned collection markup.
-
seoDomFirstFeatureBootstrapScriptHtml(
Set< SeoDomFirstFeature> features, {String? nonce}) → String - Returns the package-owned pre-paint bootstrap for selected features.
-
seoDomFirstFeatureScriptHtml(
Set< SeoDomFirstFeature> features, {String? nonce}) → String -
Returns the compiled runtime needed by the selected DOM-first
features. -
seoDomFirstFeatureStyleHtml(
Set< SeoDomFirstFeature> features, {String? nonce}) → String -
Returns the style tag needed by the selected DOM-first
features. -
seoInteractionScriptHtml(
{String? nonce}) → String - Wraps the trusted runtime in an inline script tag.
-
seoInteractionStyleHtml(
{String? nonce}) → String - Wraps the package-owned interaction CSS in a managed style tag.
-
seoLlmsFullTxt(
{required String siteBase, List< SeoRoute> ? routes, List<SeoResolvedPage> ? pages, String? title, String? description, List<String> additionalPaths = const [], int concurrency = 8}) → Future<String> - Generates an llms-full.txt: like seoLlmsTxt, but with the complete page content inlined as markdown — AI assistants get the whole site in one request instead of crawling page by page.
-
seoLlmsTxt(
{required String siteBase, List< SeoRoute> ? routes, List<SeoResolvedPage> ? pages, String? title, String? description, List<String> additionalPaths = const []}) → String - Generates an llms.txt from the SEO route table.
-
seoRedirectMiddleware(
{String? canonicalHost, bool forceHttps = false, bool trustProxy = false, bool stripTrailingSlashes = true, Map< String, String> redirects = const {}}) → Middleware - Shelf middleware for SEO-relevant 301 redirects — duplicate content under several URLs splits ranking signals, one canonical URL per page collects them.
-
seoRobotsTxt(
{required String siteBase, bool includeSitemap = true}) → String - Generates a robots.txt that allows all crawlers and announces the sitemap.
-
seoSitemapXml(
{required String siteBase, List< SeoRoute> ? routes, List<SeoResolvedPage> ? pages, List<String> additionalPaths = const []}) → String - Generates a sitemap.xml from the SEO route table.
-
serializeSeoThemePreference(
SeoThemePreference preference) → String? - Serializes a preference for storage; system mode removes the stored value.
-
submitIndexNow(
{required String siteBase, required String key, required List< String> paths, Uri? endpoint, String? keyLocation, Duration timeout = const Duration(seconds: 10)}) → Future<bool> - Submits URLs to search engines via the IndexNow protocol (https://www.indexnow.org — Bing, Seznam, Naver, Yandex share the index; Google crawls the classic way via sitemap).
-
transitionSeoCollection(
SeoCollectionState state, SeoCollectionAction action, {required List< SeoCollectionRecord> records, required int categoryCount, required int pageSize}) → SeoCollectionState - Applies one closed action and returns canonical collection state.
-
transitionSeoTabs(
SeoTabsState state, SeoTabsAction action) → SeoTabsState - Computes the next tab state without retaining state or performing effects.
-
transitionSeoTheme(
SeoThemeState state, SeoThemeAction action) → SeoThemeTransitionResult - Applies one closed theme action without retaining state or doing I/O.
Typedefs
- SeoBarChartComponentEntry = ({String label, double value})
- Pure input for one bar in buildSeoBarChartNodes.
-
SeoBodyBuilder
= FutureOr<
List< Function(Map<SeoNode> >String, String> params) - Builds the semantic HTML body for a matched route — used by the SSR server. May be asynchronous (e.g. to load content from a database).
- SeoBreadcrumbComponentEntry = ({String label, String? url})
- Pure input for one step in buildSeoBreadcrumbsNodes.
-
SeoCarouselComponentEntry
= ({String label, List<
SeoNode> nodes}) - Pure input for one slide in buildSeoCarouselNodes.
-
SeoCollectionComponentEntry
= ({List<
String> categories, List<SeoNode> nodes, String searchText, int sortKey, String title}) - Pure input for one entry in buildSeoCollectionNodes.
- SeoCollectionUrlValues = ({String? category, String? page, String? query, String? sort})
- Canonical encoded values for one collection's URL parameters.
- SeoFaqComponentEntry = ({String answer, String question})
- Pure input for one question in buildSeoFaqNodes.
-
SeoMetaBuilder
= SeoMeta Function(Map<
String, String> params) - Builds the SeoMeta for a matched route.
- A pure view of an application-specific navigation item.
-
SeoPageResolver
= FutureOr<
SeoPage?> Function(Request request) -
Maps an incoming request to the SeoPage a bot should receive,
or
nullto fall through to the regular Flutter app. -
SeoPathEnumerator
= FutureOr<
List< Function()String> > -
Lists every concrete URL a
:paramroute stands for, so the sitemap, llms.txt and the prerenderer can enumerate a pattern route. For/products/:slugit returns the actual product paths. - SeoPieChartComponentEntry = ({int? colorArgb, String label, double value})
- Pure input for one segment in buildSeoPieChartNodes.
-
SeoResolver
= FutureOr<
SeoResolution> Function(SeoRequest request) - Produces the SeoResolution for one concrete URL — metadata and body from a single read. The content source of a SeoRoute.dynamic.
-
SeoStepperComponentEntry
= ({String label, List<
SeoNode> nodes}) - Pure input for one step in buildSeoStepperNodes.
-
SeoTabComponentEntry
= ({String label, List<
SeoNode> nodes}) - Pure input for one panel in buildSeoTabsNodes.
- SeoTabsTransition = SeoTabsState Function(SeoTabsState state, SeoTabsAction action)
- A state-free tabs transition shared by platform presentations.
Exceptions / Errors
- SeoAuditFailure
- Thrown by assertSeoHealthy when a report does not pass.