Skip to main content

EverShop v2.2.1: Page Builder, Blog, Metafields and a Rebuilt Shipping Stack

· 10 min read
Evershop Team
Maintainer

EverShop v2.2.1 is out. It is the largest release since 2.0: four months of work that adds a visual page builder, a blog module, typed custom fields on every entity, a completely rebuilt shipping and fulfillment stack, built-in cloud file storage and product recommendations — on top of a move to React 19.

It also fixes several security vulnerabilities, so upgrading promptly is recommended.

🎨 Visual Page Builder

A new core module gives you drag-and-drop storefront editing at /admin/page-builder.

The EverShop page builder: a widget palette on the left with Content and Commerce categories, the live storefront canvas in the middle, and device preview, undo/redo and Publish controls in the top bar.

You compose widgets into your theme's areas and edit text and images directly on the canvas. Everything you change goes into a draft that only you see — one draft per admin, per theme — so two people can work on the same store without colliding, and nothing reaches shoppers until you publish.

When the draft is ready you can publish it immediately or schedule a rollout. Rollout plans stay editable and cancelable right up until they run, so a campaign scheduled for Friday can still be adjusted on Thursday.

The editor also gives you a layers panel, per-widget styling controls, device preview modes, undo/redo tracked per route, and a "Globals" view for areas that appear on every page.

For theme developers: a route opts into the builder by adding "editable": true to its route.json. Thirteen core routes ship with it, including the homepage, category, product, search, cart, checkout and the blog pages.

📝 Blog

A full blog module — posts, categories, tags, comments and reactions — with storefront pages, an RSS feed and page-builder widgets.

Comment moderation policy lives on the category, not the post: each category is open, moderated or closed, which lets you run an open comment section on tutorials while locking it on announcements. Posts support four reaction types; comments support likes.

Creating a blog category in the EverShop admin, with the comment policy set to Moderated — hold for review, alongside the Open and Closed options, and a Custom fields card on the same form.

Blog posts and categories are also metafield owners (below), so you can add your own typed fields to them.

🏷️ Metafields

Typed custom fields, now on products, categories, collections, customers, orders, blog posts, blog categories and the shop itself.

Ten field types ship — short text, long text, rich text, integer, number, boolean, date, colour, URL and nested groups — each available as a single value or a list. Values are validated on write against the definition, and every field declares whether it is visible to customers or admin-only, so a field marked internal never reaches the storefront GraphQL schema.

Defining a metafield in the EverShop admin: name, description, key and type, with toggles for Allow multiple, Required and Visible to customer, and a collapsible Validation section.

The part worth knowing for theme authors: a theme can declare its own field definitions in theme.json. They are provisioned when the theme is activated and re-checked on every boot, with attribution recorded so you can see which theme created which field. A new <Metafield> component renders them on the storefront.

📦 Shipping and fulfillment, rebuilt

This is the largest change in the release, and the one most likely to affect existing extensions.

Shipping is now provider-based. The old flat zone → method → rate model is gone. Zones now have providers attached to them, and each provider supplies its own methods — either statically or by quoting live rates against a carrier API, with a per-provider timeout so a slow API degrades that one provider instead of hanging checkout. Your existing zones, methods and rates are migrated automatically into a built-in Core provider that behaves like the old system.

Zones also became multi-country: a single "EU" zone can now cover every member state instead of needing one zone per country.

The Shipping Providers settings page showing the built-in Core Shipping provider with its methods, each row listing status and the zones it serves.

Fulfillment went multi-shipment. An order can now be shipped in several packages, each with its own items, status, tracking number and purchased label. The order's own shipment status became a rollup computed from those shipments — pending, partially_shipped, shipped, partially_delivered, delivered, partially_canceled or canceled — so an order with two of three parcels dispatched reports that accurately rather than being either "shipped" or not.

A shipment card on an order in the EverShop admin, listing the items in that parcel with its own Shipped status, carrier, tracking number, and per-shipment actions to mark delivered, edit tracking or cancel.

Carriers are a registry. An extension can register a carrier that creates labels, generates tracking URLs and pushes status updates back into EverShop. Purchased labels are stored against the shipment. A custom carrier ships in core for manual tracking numbers.

Packages round it out: define your box and envelope sizes once, assign one to each product, and dimensions flow through the cart into the order and on to the carrier when a label is bought.

☁️ Cloud file storage

S3, Azure Blob and Google Cloud Storage are now built into core — previously these were separate extensions.

The System Setting page in the EverShop admin, offering local file system, Amazon S3, Azure Blob Storage and Google Cloud Storage as file storage providers, with a warning that local storage is not recommended for production.

Credentials are configured on a new System Setting page and applied per call, so switching providers takes effect without a restart. Environment variables override the stored settings for anyone who prefers to keep secrets out of the database, and secrets that come from the environment render masked in the admin. The storage host is automatically allowed for the image optimizer, so images served from your bucket keep working without extra configuration.

🛒 Product recommendations

Four new shelves, all with page-builder widgets:

  • Related products — rule-based, matching on the same category, collection or attribute values, with an optional price band and manual overrides per product.
  • Frequently bought together — derived from real co-purchase statistics using association confidence and lift, rebuilt nightly and on demand.
  • Upsell — derived automatically from your related-products rules, restricted to pricier items. Nothing to configure.
  • Cart cross-sell — aggregates co-purchase candidates across everything in the cart, excluding what's already in it.

Each product can inherit the global rules, override them, or pin manual picks — and the edit page previews exactly what shoppers will see, with the reason each match was chosen.

The Recommendations card on a product edit page, with rules set to inherit category or global rules, a manual picks list, and a preview of what shoppers will see, annotated with why each product matched.

⚛️ React 19

The framework moved from React 17 to React 19. Because EverShop resolves React through a single hoisted copy, your theme and extensions run on it too.

Most of the breaking changes fail silently — no build error, just a blank area or an ignored default at runtime. Upgrading Your Theme And Extensions To React 19 walks through every one and its fix.

And more

  • Landing pages — standalone marketing pages built entirely in the page builder, served at root-level URLs, with duplication and scheduling.
  • Automatic URL redirects — renaming a product, category or page slug now records a redirect from the old path, so existing links and bookmarks keep working. Redirect chains collapse automatically.
  • Sitemap and robots.txt — generated automatically, refreshed on a schedule, with an extension point for adding your own URL sources.
  • CMS pages moved to root-level URLs (/about-us rather than /page/about-us), with the old paths permanently redirecting.
  • Zero-total checkout — orders that come to zero through a full discount or free products now complete through an automatic "No payment required" method instead of erroring.
  • Guest checkout toggle — enforced both on the checkout page and at order creation, so it can't be bypassed by an API client.
  • Product duplication — duplicate from the product grid into a pre-filled creation form.
  • Per-IP rate limiting — built in, with a stricter tier on login, registration and password-reset endpoints.
  • Accessibility — field errors are now wired to their inputs for screen readers, and product-card Add-to-Cart is reachable by keyboard and touch rather than hover only.
  • Large-catalog performance — several fixes found while load-testing a 500,000-product catalog, including a query pattern that could stall the event loop and a search plan that bypassed its index.

🔒 Security

This release fixes unauthenticated SSRF, an IDOR on customer endpoints, stored XSS, and an account-takeover path via a missing authorization check on customer update. All high-severity dependency alerts were cleared. If you are running 2.1.x, upgrade.

Breaking changes

The full list is in the changelog. The ones most likely to affect you:

ChangeWhat to do
React 19defaultProps is ignored on function components, propTypes is gone, and react-toastify was replaced by sonner. See the migration guide.
Shipping providersThe shipping_method and shipping_zone_method tables are dropped. Extensions built on them must move to the provider registry. Your data migrates automatically.
Multi-shipmentOrder and shipment went one-to-many. order.shipment_status is now derived — never write it directly. Shipment statuses must declare a phase.
Widget storagewidget was renamed to widget_instance and placement moved to its own table. Direct SQL against the old table breaks.
Settings moved out of config.jsonCurrency, timezone, units, branding, catalog and tax options are admin settings now, with config kept as a fallback — except themeConfig.logo, which was removed outright.
Dropped columnscategory.include_in_nav (use the menu widgets) and url_rewrite.language.
Build and depsThe --skip-minify flag and build-fast script were removed; node-cron went 3 → 4, so verify custom job schedules.

Upgrading

npm install @evershop/evershop@2.2.1
npm run build
npm run start

Or with Docker:

docker pull evershop/evershop:2.2.1
Back up your database first

This release applies 32 database migrations, several of which transform data or drop legacy tables — the shipping tables are replaced by the provider model, widget is renamed, and shipment statuses are collapsed and recomputed. Migrations run automatically on first start and there is no down-migration. Take a backup before you begin.

After upgrading:

  1. Re-upload your logo under Store Setting → Branding. themeConfig.logo was removed with no fallback.
  2. Check your shipping setup under the new provider-based settings. The data migrates automatically, but verify your rates.
  3. Rebuild your navigation with the menu widgets if it relied on include_in_nav.
  4. Verify custom cron schedules against node-cron 4.
  5. For custom themes and extensions, work through the React 19 guide — those changes don't announce themselves at build time.

Thanks

Thanks to everyone who contributed to this release and to those who reported the issues it fixes. The upgrade path from 2.1.2 was rehearsed against a seeded store before release — but if you hit something, open an issue.