serenay_ecommerce_widgets 1.5.1 copy "serenay_ecommerce_widgets: ^1.5.1" to clipboard
serenay_ecommerce_widgets: ^1.5.1 copied to clipboard

Server-driven UI for Flutter e-commerce apps: render home and category screens (banners, product carousels, grids, flash sales, stories) from backend JSON.

Serenay logo

serenay_ecommerce_widgets #

pub package pub points CI License: MIT Platform

๐Ÿš€ Live demo ยท ๐Ÿ“– Docs ยท ๐Ÿค– llms.txt

A server-driven UI (SDUI) widget system that renders e-commerce home/category screens from a backend-driven JSON payload. For the full widget catalog โ€” one usage doc per widget type, with JSON schemas and examples โ€” see doc/widgets/.

Widget catalog demo 1 Widget catalog demo 2

Installation #

dependencies:
  serenay_ecommerce_widgets: ^1.5.1

Quick start #

The package is backend-agnostic: navigation, data fetching, and auth/cart state are all injected from the host app through WidgetCallbacks.

final callbacks = WidgetCallbacks(
  onAction: (action) {
    // Navigate based on action.type (category, product, collection, ...).
  },
  fetchProducts: (query) => myApi.fetchProducts(query),
  fetchSlides: (id) => myApi.fetchSlides(id),
  isLoggedIn: () => myAuth.isLoggedIn,
  onToggleFavorite: (product) => myApi.toggleFavorite(product.id),
  onAddToCart: (product, variant, qty) => myCart.add(product, variant, qty),
);

final screenJson = await myApi.fetchScreen(); // { "data": [ ... ] }
final data = WidgetCatalog.fromJson(screenJson);

ListView(children: WidgetCatalog.getScreen(data: data, callbacks: callbacks));

Only onAction and fetchProducts are required on WidgetCallbacks; callbacks for widget types you don't use (fetchVideos, fetchModal, visitedProducts, ...) can be left unset โ€” the corresponding widget just hides itself when no data comes back, it never crashes.

See example/lib/main.dart for a complete working example: a mock JSON payload and mock callbacks driving a demo screen with every catalog widget.

Theming #

By default every widget uses the package's built-in colors and text styles. To re-brand the catalog for your app, pass an EcommerceWidgetTheme to getScreen:

final theme = EcommerceWidgetTheme(
  primaryColor: const Color(0xFF7B2CBF),
  secondaryColor: const Color(0xFFFF9F1C),
  discountColor: const Color(0xFFE63946),
  productTitleStyle: const TextStyle(fontWeight: FontWeight.w700),
);

WidgetCatalog.getScreen(data: data, callbacks: callbacks, theme: theme);

Any field you don't set falls back to the package default โ€” see EcommerceWidgetTheme for the full list of overridable colors, text styles and sizes.

The standalone building blocks the catalog composes internally โ€” AddToCartButton, FavoriteButton, DiscountBadge, QuantityPicker, RichProductCard โ€” are also exported, so you can use them directly outside WidgetCatalog (e.g. in a custom product detail screen) with their own constructor overrides.

Further customization #

Beyond EcommerceWidgetTheme, WidgetCallbacks has a few more override points for cases the theme alone can't cover:

  • formatPrice: (amount, currency) => ... โ€” replace the built-in "<amount> <symbol>" price text with your own locale/currency formatting.
  • productCardBuilder: (data) => ... โ€” replace the card CAROUSEL, PRODUCTCARD and FLASHSALE render for each product entirely (GRID keeps its own OldProductCard design regardless).
  • imageErrorBuilder: () => ... โ€” replace the broken-image placeholder shown across every widget when a network image fails to load.

GridWidget/ProductCardWidget also read a "columns" value from a widget's params (falling back to theme.gridColumns, default 2) if a backend wants a 3- or 4-column grid on a given screen.

If your backend sends a type this package doesn't ship a widget for yet, register a builder for it instead of waiting for a package update:

WidgetCatalog.registerBuilder('CUSTOM_BANNER', (entry, callbacks, theme) {
  return MyCustomBanner(params: entry.params);
});

Supported widgets #

TEXT, IMAGE, SLIDER, DIVIDER, CAROUSEL, GRID, IMAGECAROUSEL, IMAGELIST, VIDEOLIST, FASTREGISTER, STORY, VISITEDPRODUCTS, TIMEIMAGE, YOUTUBE, SEARCH, PRODUCTCARD, FLASHSALE, MODAL, MIXEDCAROUSEL, RATING, BUNDLE, COUPON, CATEGORYMENU, LOYALTYPROGRESS, COMPARISON, ABANDONEDCART, REVIEWS, QNA, URGENCY, RECOMMENDEDFORYOU, SOCIALPROOF, SIZEGUIDE, TRUSTBADGES, BRANDS, BANNERGRID, ANNOUNCEMENTBAR. An unrecognized type renders as an empty 1px box (forward compatibility).

GRID has its own card design (taller image, inline video, a pre-order banner, a size/package picker); CAROUSEL, PRODUCTCARD and FLASHSALE share the same card.

For the params schema each widget expects, see doc/widgets/ โ€” one page per widget type.

Using with Claude Code #

A Claude Code plugin ships in this repo. It teaches Claude the package's API and every widget's JSON schema, so it can wire the package into your app and write screen JSON for you:

/plugin install serenay-ecommerce-widgets --marketplace serenayyazilim/serenay-ecommerce-widgets

On older Claude Code versions: /plugin marketplace add serenayyazilim/serenay-ecommerce-widgets, then /plugin install serenay-ecommerce-widgets@serenay.

Other AI tools can read llms.txt.

Contributing #

Bug reports and PRs are welcome โ€” see CONTRIBUTING.md for setup, the widget-authoring checklist, and issue templates.

4
likes
150
points
559
downloads

Documentation

API reference

Publisher

verified publisherserenay.net.tr

Weekly Downloads

Server-driven UI for Flutter e-commerce apps: render home and category screens (banners, product carousels, grids, flash sales, stories) from backend JSON.

Repository (GitHub)
View/report issues
Contributing

Topics

#server-driven-ui #ecommerce #json-ui #dynamic-ui #widget

License

MIT (license)

Dependencies

cupertino_icons, flutter, url_launcher, video_player, youtube_player_flutter

More

Packages that depend on serenay_ecommerce_widgets