In the dynamic realm of modern web development, particularly within e-commerce, content management systems (CMS) serve as the bedrock for digital operations. While platforms like Payload CMS v3 offer solid frameworks and flexibility, the journey of deploying and scaling complex applications often reveals specific functionalities that are either nascent or entirely absent from the core ecosystem. This article delves into the journey of identifying, developing, and deploying two crucial missing components for Payload CMS v3: a comprehensive customer reviews system with administrative moderation and Google star ratings integration, and a complete Schema.org JSON-LD solution designed to enhance Google rich snippets for e-commerce products.

The experience, forged through the intensive operation of 23 distinct European e-commerce shops, each leveraging Next.js and Payload CMS v3, underscores a universal truth in software development: no platform, Even so sophisticated, can anticipate every single niche requirement. This narrative explores the technical intricacies, unexpected challenges, and innovative solutions devised to bridge these critical gaps, ultimately enriching the Payload CMS ecosystem and providing invaluable lessons for developers tackling similar customisation projects.

The Multi-Clone E-commerce Architecture: A Foundation for Discovery

Our operational context revolved around a sophisticated multi-clone e-commerce infrastructure. This setup comprised 23 individual online stores, all powered by a unified codebase built with Next.js for the frontend and Payload CMS v3 for content and data management. Each store operated on its own subdomain—for instance, fr.myshop.com for France, de.myshop.com for Germany, and sk.myshop.com for Slovakia—and catered to specific linguistic and regional requirements. This architecture, while incredibly efficient for managing a large portfolio of shops from a single source, inevitably highlighted areas where generic CMS functionalities fell short of highly specialized e-commerce demands.

The beauty of such a system lies in its ability to deploy country-specific patches and content variations without duplicating the entire codebase. However, this level of granular control and localization also amplified the need for features that directly impact user trust and search engine visibility—two non-negotiable elements for any successful e-commerce venture. It was within this demanding production environment that the absence of certain key functionalities became glaringly apparent, prompting a deep look closely at custom plugin development to ensure the continued success and competitiveness of these digital storefronts.

Identifying Critical Gaps in Payload v3's Ecosystem

Despite Payload CMS v3's growing popularity and a burgeoning official plugin ecosystem covering essential areas like SEO meta tags, forms, and redirects, two significant pieces of the e-commerce puzzle remained conspicuously absent. These were functionalities that, while often taken for granted in more mature e-commerce platforms, were simply not available as ready-to-use solutions for Payload v3:

  • A robust customer reviews system, complete with administrative moderation capabilities and the crucial ability to render Google star ratings in search results.
  • A comprehensive implementation of Schema.org JSON-LD structured data, specifically tailored for e-commerce entities such as Product, BreadcrumbList, ItemList, and AggregateRating, vital for achieving rich snippets in Google search results.

The absence of these features represented not just a minor inconvenience but a substantial impediment to maximising conversion rates, building customer trust, and achieving optimal search engine visibility across all 23 e-commerce shops. Recognizing the strategic importance of these elements, the decision was made to engineer bespoke solutions, transforming these missing links into powerful, production-ready plugins for the Payload CMS community.

Developing the Customer Reviews Plugin for Payload CMS

The journey to create a fully functional customer reviews system began with addressing the fundamental void in the Payload v3 plugin ecosystem. A quick search on npm for "payload reviews" or "payload ratings" for version 3 yielded no viable results, confirming the need for an original solution. The objective was clear: build a system that allows customers to submit reviews, provides administrators with moderation tools, and integrates with Google's rich snippets for star ratings.

Manual Database Migration for New Collections

A final operational note pertained to database schema management. When running Payload in development mode with `batch: -1`, new collections like `reviews` might not auto-migrate their corresponding database tables upon application build. This necessitated manual SQL intervention to create the `reviews` table and its associated enum type (`enum_reviews_status`), as well as updating relationship tables (`payload_locked_documents_rels`). This step is a reminder that while ORMs simplify database interactions, understanding the underlying schema and migration processes remains crucial for robust application deployment.

The `payload-plugin-reviews` is now available on npm, offering a robust, production-tested solution for integrating customer reviews into Payload CMS v3 e-commerce platforms.

Crafting the JSON-LD Plugin for Enhanced SEO

While Payload's official SEO plugin capably handles meta tags and other on-page SEO elements, it notably lacks support for Schema.org structured data. This omission meant foregoing the significant benefits of Google rich snippets—those visually appealing enhancements in search results that can dramatically improve click-through rates. The goal was to develop a comprehensive JSON-LD solution, `payload-plugin-seo-jsonld`, specifically tailored for e-commerce sites running on Payload v3, ensuring full compliance with Google's Rich Results validation.

The plugin's development was informed by extensive real-world testing across 23 production e-commerce shops, guaranteeing that the generated JSON-LD not only conformed to Schema.org standards but also passed Google's strict validation tests for various schema types relevant to e-commerce, including Product, BreadcrumbList, ItemList, and AggregateRating.

Navigating Payload v3's Custom Endpoint Limitations

Another significant hurdle involved registering custom API endpoints. An attempt to define a parameterized GET endpoint like `/reviews/product/:productId` directly within `payload.config.ts` resulted in a "Route not found" error. This revealed a limitation in how Payload v3 mounts parameterized custom endpoints under its default `/api` prefix. The solution required an architectural shift: instead of relying on Payload's internal endpoint registration for this specific use case, a Next.js App Router route was utilised.

By defining the API route within `src/app/(app)/api/reviews/product/[productId]/route.ts`, the Next.js framework could correctly handle the parameterized segment. Inside this Next.js API route, Payload's `payload.find()` method was then invoked to query the `reviews` collection, filtering by `productId` and `status: 'approved'`. This approach not only bypassed the Payload endpoint limitation but also demonstrated the flexibility of integrating Payload's powerful data layer with Next.js's routing capabilities.

Overcoming Relationship Field Anomalies

A peculiar bug surfaced during the submission of review forms: Payload would reject the `product` relationship field, reporting an invalid relationship value like `"108 0"` instead of the expected integer `108`. This indicated an unexpected type coercion issue where the product ID, intended as a number, was being transmitted as a string with an appended space and zero. The fix, though simple, was critical: explicitly parse the `productId` to an integer using `parseInt(productId, 10)` before sending it in the JSON payload. This ensures strict type adherence, preventing database rejections and maintaining data consistency.

Navigating Schema.org Specifics: Price and LowPrice

One of the initial stumbling blocks involved the specific properties required for pricing within Schema.org's `AggregateOffer` type. Google's Rich Results validator explicitly rejects the use of a generic `price` property in this context, instead requiring `lowPrice` for offers that represent a range or an aggregated offer. This seemingly minor distinction is critical for successful validation and highlights the need for precise adherence to Schema.org guidelines to unlock rich snippet potential.

Ensuring Data Integrity and Security

Beyond basic access control, maintaining data integrity and protecting sensitive information were paramount. For instance, preventing users from self-verifying their reviews was a crucial security measure. In collections where `create: () => true` allows public POST requests, users could potentially manipulate fields like `verified`. The solution involved implementing a `beforeChange` hook within the review collection's configuration. This hook would automatically set `verified` to `false` and ensure the `status` defaults to 'pending' upon creation, thereby reserving the `verified` flag for administrative approval only.

Similarly, public exposure of author email addresses, even in a `read: () => true` collection, presents a privacy risk. To mitigate this, field-level access control was applied to the `authorEmail` field. This ensured that only authenticated users with 'admin' roles could read this sensitive information, while the review content itself remained publicly accessible. This granular control over data visibility is a cornerstone of secure web application development.

Constructing the Review Collection and Addressing Access Control

The core of the plugin involved creating a `reviews` collection within Payload. This collection was designed to be straightforward, establishing a clear relationship with the `products` collection, storing a `rating` (from 1 to 5), managing a `status` (pending, approved, or rejected), and capturing author details. However, several nuances quickly emerged, particularly concerning access control in Payload v3.

One significant "gotcha" involved the evolution of user access patterns from Payload v2 to v3. Unlike v2, which might have relied on a single `role` string, Payload v3 employs a `roles` array. This distinction is critical; attempting to replicate v2's `req.user?.role === 'admin'` pattern for update access would invariably return false. The correct approach for v3 necessitated checking if the `roles` array includes 'admin', using `req.user?.roles?.includes('admin')`. This seemingly minor change highlights the importance of understanding platform-specific API shifts when migrating or developing for new versions.

Accurate Price Representation: From Cents to Currency

Another common pitfall in e-commerce applications is how prices are stored. Many systems, including the one in our architecture, store prices in cents (e.g., `3990` for €39.90) to avoid floating-point inaccuracies. Directly passing these raw integer values to Google's JSON-LD would result in incorrect and misleading rich snippets, potentially displaying a €3,990 bracelet instead of a €39.90 one. The solution was straightforward but essential: divide the stored integer price by 100 and format it to two decimal places using `.toFixed(2)` before embedding it in the JSON-LD payload. This ensures that prices are accurately represented in the currency expected by search engines and users.

Preventing ItemList Duplication Errors

A more subtle but equally impactful issue arose with `ItemList` JSON-LD scripts. Google's validator has a strict policy: if a page contains two `ItemList` scripts, it invalidates both. This problem manifested in shops where a carousel from a base template might generate one `ItemList`, and then a newly patched-in carousel or product listing widget would generate another. The solution involved careful design within the plugin to ensure that only a single, valid `ItemList` script is outputted per page. This often meant implementing logic to return `null` when a product list was empty or ensuring that only one instance of the `ItemList` generation mechanism was active, thereby adhering to the single-instance contract required for successful Google validation.

The `payload-plugin-seo-jsonld` now provides a robust, battle-tested solution for injecting accurate and comprehensive Schema.org structured data into Payload CMS v3 e-commerce sites, significantly enhancing their visibility and presentation in search engine results pages.

What This Means for Developers

From Voronkin Studio's perspective, the development and deployment of these custom Payload CMS v3 plugins offer profound insights for web development agencies, freelance developers, and in-house project teams. Firstly, it underscores the critical importance of evaluating a CMS's plugin ecosystem not just for its breadth but for its depth and specific applicability to client needs. While open-source platforms like Payload CMS provide immense flexibility, relying solely on out-of-the-box solutions can lead to functional gaps, particularly in specialized domains like e-commerce. Agencies must budget for and proactively identify opportunities for custom development, recognizing that bespoke solutions can be a significant competitive differentiator and value-add for clients seeking advanced performance.

Secondly, this experience highlights the necessity for developers to possess a deep understanding of the underlying platform's architecture and its evolution. The nuances encountered with Payload v3's access control, custom endpoint routing, and database migration processes are not mere technicalities; they are indicative of the continuous learning and adaptation required to build resilient applications. For client projects, this translates into more robust, future-proof implementations. Voronkin Web Development advocates for a proactive approach where developers are not just coders but problem-solvers who can anticipate potential pitfalls and architect solutions that go beyond the obvious, ensuring client applications remain performant and scalable.

Finally, the emphasis on Google Rich Results through Schema.org JSON-LD is a potent reminder of the intersection between technical development and business outcomes. High-quality structured data is not merely an SEO checkbox; it directly impacts organic visibility, click-through rates, and ultimately, conversion. Web agencies should integrate comprehensive JSON-LD strategies into every e-commerce project from inception, educating clients on its value. Developers should treat Schema.org implementation with the same rigor as core business logic, understanding that accurate, valid structured data can be a powerful engine for client success, transforming search engine visibility into tangible revenue growth. Embracing such an approach is fundamental to delivering exceptional value in today's competitive digital landscape.

Conclusion

The journey of building these two critical plugins for Payload CMS v3—a robust customer reviews system and a comprehensive JSON-LD solution—illustrates the ongoing evolution of web development and the necessity for adaptability. Even with powerful and flexible content management systems, specific business requirements often necessitate custom engineering. The challenges encountered, from subtle access control changes to complex JSON-LD validation rules, provide a valuable roadmap for developers navigating similar landscapes.

Ultimately, these developments not only enhance the capabilities of Payload CMS for e-commerce but also serve as a testament to the power of open-source contributions. By addressing real-world production needs, developers can empower businesses to achieve greater online presence, build stronger customer trust, and unlock their full e-commerce potential, one custom solution at a time. The lessons learned here are universally applicable, emphasizing diligence, a keen eye for detail, and a commitment to solving problems that truly matter for end-users and businesses alike.

Related Reading

Need expert web development services for your next project? Voronkin Studio works with clients across Canada, USA, and France.