PHPackages                             bymayo/vouch - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. bymayo/vouch

ActiveCraft-plugin[Utility &amp; Helpers](/categories/utility)

bymayo/vouch
============

Customer reviews for Craft CMS - pull from Google, Trustpilot, Feefo and Reviews.io, or collect your own.

5.0.2(1w ago)00proprietaryPHPPHP &gt;=8.2CI passing

Since May 27Pushed 1w agoCompare

[ Source](https://github.com/bymayo/craft-vouch)[ Packagist](https://packagist.org/packages/bymayo/vouch)[ RSS](/packages/bymayo-vouch/feed)WikiDiscussions craft-5 Synced 1w ago

READMEChangelog (3)Dependencies (2)Versions (4)Used By (0)

[![](https://raw.githubusercontent.com/bymayo/craft-vouch/craft-5/src/icon.svg)](https://raw.githubusercontent.com/bymayo/craft-vouch/craft-5/src/icon.svg)

Vouch for Craft CMS 5
=====================

[](#vouch-for-craft-cms-5)

Pull customer reviews from Google, Trustpilot, Feefo and Reviews.io straight into Craft - or collect your own through the CP and a front-end form. Relate ratings to any element (entries, products, users, categories - you name it), block the spam, and render everything through Twig or GraphQL. You can also view and approve reviews straight from your dashboard with built-in widgets.

[![](https://raw.githubusercontent.com/bymayo/craft-vouch/craft-5/resources/screenshot.png)](https://raw.githubusercontent.com/bymayo/craft-vouch/craft-5/resources/screenshot.png)

Features
--------

[](#features)

- **Multiple providers** - Google, Trustpilot, Feefo, Reviews.io (with more on the way), plus a Manual source for CP and front-end submissions
- **Renameable** - call it "Reviews", "Testimonials", "VIP Feedback"… whatever fits the site
- **Per-source moderation** - manual approval, minimum ratings, auto-approve thresholds
- **Front-end submission form** - CSRF, validation, length caps, honeypot and per-IP rate limiting baked in
- **User matching** - reviews automatically link back to existing Craft users when the email matches an account
- **Element-index integration** - Rating column on Entries and Commerce Products, Reviews count column on Users, plus a "Reviews" tab on the user edit page
- **Dashboard widgets** - Reviews Pending Approval, Latest Reviews, Top Reviewed Elements, and a Sources widget with one-click sync
- **Bulk approve** - tidy up the pending queue in one go
- **Granular permissions** - View / Create / Edit / Delete / Approve / Sync, each on its own switch
- **Developer APIs** - chainable Twig query, GraphQL types and queries, and events for your own integrations
- **Cron syncing** - schedule pulls per source or all at once, with sync buttons throughout the CP for ad-hoc runs
- **Points integration** - award loyalty points or site credit when a review is approved (requires the [Points](https://plugins.craftcms.com/points?craft5) plugin)

Tip

📦 **Part of a suite.** A wider set of plugins built for Commerce stores - pair them up for a more complete setup:

- [Vouch](https://plugins.craftcms.com/vouch?craft5) - pull and manage customer reviews from Google, Trustpilot, Feefo and Reviews.io
- [Commerce Widgets](https://plugins.craftcms.com/commerce-widgets?craft5) - sales, revenue and order dashboard widgets for your Commerce store
- [Points](https://plugins.craftcms.com/points?craft5) - reward customers with loyalty points or site credit to spend at checkout
- [Curated](https://plugins.craftcms.com/curated?craft5) - build hand-picked product collections for your Commerce store

Contents
--------

[](#contents)

- [Install](#install)
- [Requirements](#requirements)
- [Providers](#providers)
- [Setting up a source](#setting-up-a-source)
    - [Google Reviews](#google-reviews)
    - [Trustpilot](#trustpilot)
    - [Feefo](#feefo)
    - [Reviews.io](#reviewsio)
    - [Manual](#manual)
- [Front-end review submissions](#front-end-review-submissions)
- [Twig](#twig)
- [Sync](#sync)
- [Attribution &amp; spam controls](#attribution--spam-controls)
- [Element integration](#element-integration)
- [Dashboard widgets](#dashboard-widgets)
- [Settings](#settings)
- [GraphQL](#graphql)
- [Events](#events)
- [Nice to know](#nice-to-know)
- [Support](#support)

Install
-------

[](#install)

- Install with Composer via `composer require bymayo/craft-vouch` from your project directory
- Enable / Install the plugin in the Craft Control Panel under `Settings > Plugins`

You can also install the plugin via the Plugin Store in the Craft Admin CP by searching for `Vouch`.

Requirements
------------

[](#requirements)

- Craft CMS 5.6+
- PHP 8.2+

Providers
---------

[](#providers)

ProviderBacked byAuthGoogle ReviewsPlaces API (New) or Business Profile APIAPI key, or OAuth 2.0TrustpilotPublic Business Units APIAPI key + Business Unit IDFeefoReviews API v20Merchant identifier + optional API keyReviews.ioMerchant Reviews APIStore ID + API keyManualAuthored in the CP or via front-end formn/aSetting up a source
-------------------

[](#setting-up-a-source)

A source is a single feed of reviews tied to a provider. You might set up a Google Reviews source to pull in your overall company reviews, a Reviews.io source for product reviews, or a Manual source for testimonials you collect yourself - you can have as many as you like, mixing and matching providers as you go.

Head to **Vouch → Sources → New source**, choose your provider, fill in the credentials and Save. A "Test connection" check runs automatically on the edit page so you'll know straight away if something's off.

### Google Reviews

[](#google-reviews)

Google sources have a **Mode** dropdown:

- **Places API** - works for any place, but Google caps you at 5 reviews per call
- **Business Profile API** - only for businesses you (or the OAuth-connecting account) own or manage. Full review history with pagination, but needs Google partner approval - more on that below

#### Places API mode

[](#places-api-mode)

1. Open the [Google Cloud Console](https://console.cloud.google.com) and create (or select) a project.
2. Enable the **Places API (New)** under **APIs &amp; Services → Library**.
3. Create an API key under **APIs &amp; Services → Credentials → Create credentials → API key**.
4. **Worth doing:** restrict the key. In its settings, set "Application restrictions" to your server IP(s) and "API restrictions" to Places API (New) only - if the key ever leaks, it can't be re-used for billed Maps calls.
5. In Vouch, leave **Mode** on "Places API", paste your API key, then use the built-in **"Find a Place ID"** search box. Type a company name, address or postcode and hit **Search** - Vouch proxies Google's Text Search endpoint server-side and shows the matches. Click one and the Place ID fills in for you.

    Already got a Place ID from Google's [Place ID Finder](https://developers.google.com/maps/documentation/places/web-service/place-id)? Paste it in manually instead.

> ⚠ Heads up: Google only ever returns **the 5 most recent reviews** on the Places API, and there's no way around it - that's just how their API works. Don't worry though, re-syncing won't create duplicates, you'll always just get the latest 5. **Set `backfillDays` to `0` for Places-mode sources** so you grab everything available.

#### Business Profile API mode

[](#business-profile-api-mode)

> ⚠ **Heads-up: Google gatekeeps this endpoint.** Back in 2023 Google clamped down on programmatic access to reviews via the Business Profile API. To use this mode in production:
>
> 1. Apply via [Google's Business Profile API form](https://support.google.com/business/contact/api_default).
> 2. Get an OAuth 2.0 consent screen verified by Google (its own review process if your scope is "sensitive").
> 3. Wait for approval - usually weeks, and first-time applicants are often turned down.
>
> Without approval the OAuth flow completes fine, but the reviews endpoint comes back with `403 PERMISSION_DENIED`.

Once you're approved:

1. Enable the **My Business Account Management API**, **My Business Business Information API**, and the **Business Profile API** in Google Cloud Console.
2. Create an **OAuth 2.0 Client ID** of type "Web application". Add `https:///admin/actions/vouch/sources/google-oauth-callback` to "Authorized redirect URIs", then jot down the Client ID and Client Secret.
3. In Vouch: **Add source → Google Reviews**, switch **Mode** to "Business Profile API", paste in the Client ID + Client Secret and Save.
4. Reload, click **"Connect Google account"** and approve on Google's consent screen. The OAuth callback stores an encrypted refresh token on the source.
5. Fill in the **Location resource name** (`accounts/{accountId}/locations/{locationId}`). You can list your accounts/locations via the [API explorer](https://developers.google.com/my-business/reference/businessinformation/rest/v1/accounts.locations/list) or a quick `curl` against `https://mybusinessaccountmanagement.googleapis.com/v1/accounts`. Save again.
6. Hit **"Test connection"** to make sure everything's talking.

### Trustpilot

[](#trustpilot)

1. Sign in to [Trustpilot Business](https://business.trustpilot.com).
2. Generate an API key under your account's API / Integrations settings. The public tier is plenty for pulling reviews of your own business unit.
3. In Vouch, paste the API key, then use the built-in **"Find a Business Unit"** search box. Type your company name or domain, hit **Search**, and click a match to fill in the Business Unit ID for you.

    Already got the Business Unit ID? Just paste it in manually.

### Feefo

[](#feefo)

1. Your **Merchant identifier** is the slug in your Feefo dashboard URL.
2. An **API key** is optional. Public review data flows without one; private fields (e.g. customer email) need a paid plan and a bearer key.
3. Paste the merchant identifier and (optionally) the API key into the Feefo source edit page.

Without an API key, reviewer emails come through as `null` and user-matching won't fire.

### Reviews.io

[](#reviewsio)

1. Sign in to [your Reviews.io merchant dashboard](https://dash.reviews.io).
2. **Integrations → API**: copy your **Store ID** (merchant code) and **API key**.
3. Paste both into the Reviews.io source edit page.

Reviewer email is passed through when present, so user-matching works out of the box.

### Manual

[](#manual)

No external credentials needed. Add a Manual source to:

- Author reviews directly in the CP via the **+ New review** button.
- Collect reviews through a front-end form (see [Front-end review submissions](#front-end-review-submissions) below).

Manual sources can still have `Require manual approval` toggled on - moderation respects the same `autoApproveThreshold` setting as the API-backed sources.

Front-end review submissions
----------------------------

[](#front-end-review-submissions)

Drop a form on your front-end so customers can leave reviews directly through your site. Submissions are accepted against Manual sources only.

On a failed submission, Vouch repopulates a `review` variable with the user's input and errors.

```
{% set vouchSettings = craft.vouch.settings %}

  {{ csrfInput() }}

  {# Optional: tie the review to a specific entry / product #}

  {# Honeypot - real users won't fill this, but bots will #}

  {# Show any error returned after submission #}
  {% set errorMsg = craft.app.session.getFlash('error') %}
  {% if errorMsg %}
    {{ errorMsg }}
  {% endif %}

  Rating *

    Choose a rating…
    5 ★★★★★
    4 ★★★★
    3 ★★★
    2 ★★
    1 ★

  {% for err in (review.getErrors('rating') ?? []) %}{{ err }}{% endfor %}

  Headline *

  {% for err in (review.getErrors('headline') ?? []) %}{{ err }}{% endfor %}

  Review *
  {{ review.review ?? '' }}
  {% for err in (review.getErrors('review') ?? []) %}{{ err }}{% endfor %}

  Reviewer name *

  {% for err in (review.getErrors('reviewerName') ?? []) %}{{ err }}{% endfor %}

  Reviewer email *

  {% for err in (review.getErrors('reviewerEmail') ?? []) %}{{ err }}{% endfor %}

  Submit review

```

FieldRequiredNotes`sourceHandle`YesThe handle of the Manual source to submit against`rating`YesNumeric rating from 1-5`headline`YesShort title for the review`review`YesThe review body`reviewerName`YesDisplay name shown alongside the review`reviewerEmail`YesUsed for moderation and user matching`relatedElementId`NoTie the review to a specific entry, product, user, etc.`vouchHoneypot`NoHidden honeypot - leave empty. Any value silently discards the submissionTwig
----

[](#twig)

Because Vouch pulls reviews from every provider into a single store, you can mix and slice them however you like from one Twig API. Here are some real-life examples you can drop straight into a template.

### Overall rating across all sources

[](#overall-rating-across-all-sources)

Drop this in a footer, homepage hero, or trust banner.

```
{% set average = craft.vouch.averageRating() %}
{% set count = craft.vouch.reviews().count() %}

{% if count %}
  Rating: {{ average|number_format(1) }} ★ ({{ count }} {{ count == 1 ? 'review' : 'reviews' }})
{% endif %}
```

### Rating for a single entry or product

[](#rating-for-a-single-entry-or-product)

Use on a product or entry detail page to show that element's own rating.

```
{% set rating = craft.vouch.rating(entry.id) %}
{% set count = craft.vouch.reviews().relatedElementId(entry.id).count() %}

{% if rating %}
  {{ rating|number_format(1) }} ★ ({{ count }} {{ count == 1 ? 'review' : 'reviews' }})
{% endif %}
```

### Listing the latest reviews

[](#listing-the-latest-reviews)

```
{% for review in craft.vouch.reviews().limit(5).all() %}

    {{ review.headline ?: review.reviewerName }}
    {{ review.rating }} ★ - {{ review.reviewedAt|date('M j, Y') }}
    {{ review.review }}

{% endfor %}
```

### A user's own reviews on their profile page

[](#a-users-own-reviews-on-their-profile-page)

Pulls reviews where the reviewer's email matched a Craft user account.

```
{% set userReviews = craft.vouch.reviews().reviewerUserId(currentUser.id).all() %}

Your reviews ({{ userReviews|length }})

{% for review in userReviews %}

    {{ review.headline }}
    {{ review.rating }} ★ - {{ review.sourceName }} - {{ review.reviewedAt|date('M j, Y') }}
    {{ review.review }}

{% else %}
  You haven't left any reviews yet.
{% endfor %}
```

### Per-source breakdown for an element

[](#per-source-breakdown-for-an-element)

Useful when you're pulling reviews from more than one provider and want to show each one's average side-by-side.

```
{% for row in craft.vouch.ratingsBySource(entry.id) %}
  {{ row.sourceName }}: {{ row.average|number_format(1) }} ★ ({{ row.count }})
{% endfor %}
```

### Filtering by source and rating

[](#filtering-by-source-and-rating)

Grab the high-rated reviews from one source.

```
{% set googleReviews = craft.vouch.source('googleReviews') %}
{% set positive = craft.vouch.reviews().sourceId(googleReviews.id).rating('>= 4').all() %}
```

### Review properties

[](#review-properties)

Each review element returned by `craft.vouch.reviews()` exposes:

CallReturns`review.headline`The review's short title`review.review`The review body text`review.rating`Numeric rating from 1-5`review.reviewerName`Display name of the reviewer`review.reviewerEmail`Reviewer's email (when available)`review.reviewedAt`Date the review was left`review.sourceName`The source's display name (e.g. "Google UK")`review.sourceHandle`The source's machine handle`review.providerHandle`The connector handle (`google`, `trustpilot`, `feefo`, `reviewsio`, `manual`)`review.reviewerUser`The Craft `User` element when the reviewer's email matched an account, otherwise `null`### Full Twig API

[](#full-twig-api)

CallReturns`craft.vouch.reviews()`Review query. Chainable filters: `.sourceId(id)`, `.externalId(str)`, `.rating(value)`, `.approved(bool|null)`, `.reviewerUserId(id)`, `.relatedElementId(id)`. Defaults to approved-only - pass `.approved(false)` for pending only or `.approved(null)` for both.`craft.vouch.sources()`All `Source` models`craft.vouch.source(handle)`A single `Source` by handle`craft.vouch.sourceById(id)`A single `Source` by id`craft.vouch.providers()`All registered connectors`craft.vouch.averageRating(sourceId?)`Site-wide or per-source average rating`craft.vouch.rating(elementId)`Average rating across approved reviews for one element`craft.vouch.ratingsBySource(elementId)`Per-source rows of `{sourceId, sourceName, providerHandle, average, count}``craft.vouch.settings`The plugin's settings model (e.g. `craft.vouch.settings.pluginName`)Sync
----

[](#sync)

Set up a cron job to pull in new reviews on a schedule. You decide how often it runs.

```
# Every enabled source, hourly
0 * * * *  php craft vouch/sync/all

# Different cadence per source - the last bit is the source's handle
0 * * * *  php craft vouch/sync/source google-uk
0 4 * * *  php craft vouch/sync/source trustpilot-main
```

The argument on `vouch/sync/source` is the **handle** you set when creating the source (visible in the Sources index). You can also hit the **Sync** button on the Sources index, the source edit page, or the dashboard widget for an ad-hoc pull.

Attribution &amp; spam controls
-------------------------------

[](#attribution--spam-controls)

Vouch has a few protections built in to stop fake or forged reviews coming through your front-end form.

### How emails are handled

[](#how-emails-are-handled)

The reviewer's email is stored for moderation and contact only. A review is only linked to a Craft user when the submitter is logged in and uses their own account email - so no one can claim to be someone else.

### Blocking impersonators

[](#blocking-impersonators)

`requireLoginForKnownEmails` (on by default) rejects any submission whose email already belongs to a Craft user, unless they're logged in as that user.

### Locking it down further

[](#locking-it-down-further)

Vouch comes with a honeypot field and per-IP rate limiting baked in - just include the `vouchHoneypot` input in your form (see the example above) and tweak `submissionRateLimit` / `submissionRateWindow` in Settings to taste. For extra peace of mind:

- Turn on **"Require manual approval"** on the source so reviews stay Pending until an admin approves them.
- Restrict the form to logged-in users with `{% requireLogin %}`.
- Add a CAPTCHA (hCaptcha / reCAPTCHA) if you're getting a lot of traffic from anonymous users.

Reviews that aren't from Manual sources (e.g. Google, Trustpilot, etc.) don't go through any of this - those emails come straight from the provider.

Element integration
-------------------

[](#element-integration)

Vouch wires ratings into Craft's own element indexes and edit pages so reviews surface where you'd expect them. Each column is opt-in - turn it on via the column settings cog on the element index.

ElementWhat you getHow to enable**Entries**Rating column on the index + sidebar block on the edit page with the average and per-source breakdown.Index → cog → tick **Rating****Commerce Products**Same as Entries.Index → cog → tick **Rating****Users**Reviews count column on the index + a **Reviews** tab on the edit page listing reviews they've authored.Index → cog → tick **Reviews**Dashboard widgets
-----------------

[](#dashboard-widgets)

Add via the Craft dashboard → **+ New widget**.

WidgetShowsSettings**Reviews Pending Approval**Reviews waiting to be approved.`limit`**Latest Reviews**The most recent approved reviews.`limit`, `sourceId`**Top Reviewed Elements**Elements ranked by review count or average rating.`elementType`, `sectionId`, `sort`, `limit`**Sources**Each source with its last-synced timestamp and a one-click Sync button. Manual sources are excluded.`sourceId`Settings
--------

[](#settings)

Settings live at **Settings → Plugins → Vouch** in the CP, and can be overridden per environment via `config/vouch.php`.

SettingDefaultWhat it does`pluginName``Vouch`Plugin name shown in the CP.`matchAuthorsToUsers``true`Link reviewer emails to Craft users.`emailRetentionDays``365`Days to keep reviewer emails. `0` = forever.`backfillDays``90`History to pull on first sync. `0` = everything.`autoApproveThreshold``5.0`Auto-approve reviews at or above this rating.`requireLoginForKnownEmails``true`Block submissions using an email already tied to a Craft user.`headlineMaxLength``120`Max headline length. `0` = no limit.`reviewMaxLength``2000`Max review body length. `0` = no limit.`submissionRateLimit``5`Max submissions per IP per window. `0` = no limit.`submissionRateWindow``60`Rate-limit window in seconds.GraphQL
-------

[](#graphql)

```
{
  vouchReviews(minRating: 4, limit: 10) {
    id
    rating
    headline
    review
    reviewerName
    reviewedAt
    providerHandle
    sourceName
  }
}
```

Public GraphQL queries default to `approved: true` so pending-moderation reviews never leak. Admins can override with `approved: false` when they need to.

QueryArgsReturns`vouchReviews``sourceId`, `rating`, `minRating`, `approved`, `reviewerUserId`, `relatedElementId`, `limit`, `offset``[VouchReview]``vouchReview``id: Int!``VouchReview`Events
------

[](#events)

```
use bymayo\vouch\events\ReviewApprovalEvent;
use bymayo\vouch\services\Reviews;
use yii\base\Event;

Event::on(
    Reviews::class,
    Reviews::EVENT_AFTER_APPROVE_REVIEW,
    function (ReviewApprovalEvent $event) {
        // $event->review  - the Review element
        // $event->source  - the Source the review came from
        // $event->auto    - true if approved on sync, false if manually approved
    }
);
```

EventWhen it fires`Reviews::EVENT_AFTER_SYNC_REVIEW`After a review is created or updated during sync. `$event->isNew` tells you which.`Reviews::EVENT_AFTER_APPROVE_REVIEW`Once per review, the moment it goes live. Won't re-fire on re-syncs.`Sync::EVENT_BEFORE_SOURCE_SYNC`Just before a source syncs. Set `$event->cancelled = true` to skip it.`Sync::EVENT_AFTER_SOURCE_SYNC`After a source sync finishes. `$event->result` has the counts and any errors.Nice to know
------------

[](#nice-to-know)

### Permissions

[](#permissions)

Vouch adds its own permissions group to each user group's permissions page - View / Create / Edit / Delete for reviews and sources, plus Approve, Trigger sync, Use widgets and Manage settings.

### Bulk approving reviews

[](#bulk-approving-reviews)

On the Reviews element index, select any pending reviews and use the **Bulk Approve** action to approve them all in one go.

### Renaming the plugin

[](#renaming-the-plugin)

Vouch picks up whatever you set as `pluginName` in Settings - so you can call it whatever suits your site, e.g. Reviews, Testimonials, Feedback.

### Points integration

[](#points-integration)

If you've got [Points](https://plugins.craftcms.com/points?craft5) installed, Vouch automatically registers a **Review approved** trigger so you can award points (or site credit) whenever a customer's review goes live. Build a rule in Points → Rules pointed at that trigger and optionally narrow it down with the bundled conditions:

ConditionWhat it does**Is from source**Only fire for reviews from specific sources - e.g. more points for Google than Trustpilot.**Rating is at least**Only fire when the review's rating meets a minimum (e.g. 4★+ only).**Review length is at least**Only fire when the body meets a minimum character count - encourages thoughtful reviews over one-liners.Points are only awarded for reviews tied to a Craft user (matched by email).

Support
-------

[](#support)

If you have any issues (surely not!) I'll aim to reply as soon as possible. If it's a site-breaking-oh-no-what-has-happened moment, hit me up on the Craft CMS Discord - `@bymayo`.

###  Health Score

40

—

FairBetter than 86% of packages

Maintenance98

Actively maintained with recent releases

Popularity0

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity48

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~0 days

Total

3

Last Release

13d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/522877?v=4)[Jason Mayo](/maintainers/bymayo)[@bymayo](https://github.com/bymayo)

---

Top Contributors

[![bymayo](https://avatars.githubusercontent.com/u/522877?v=4)](https://github.com/bymayo "bymayo (51 commits)")

### Embed Badge

![Health badge](/badges/bymayo-vouch/health.svg)

```
[![Health](https://phpackages.com/badges/bymayo-vouch/health.svg)](https://phpackages.com/packages/bymayo-vouch)
```

###  Alternatives

[spicyweb/craft-neo

A Matrix-like field type with block hierarchy

393808.8k10](/packages/spicyweb-craft-neo)[craftcms/feed-me

Import content from XML, RSS, CSV or JSON feeds into entries, categories, Craft Commerce products, and more.

294943.4k27](/packages/craftcms-feed-me)[verbb/formie

The most user-friendly forms plugin for Craft.

100387.6k57](/packages/verbb-formie)[solspace/craft-freeform

The most flexible and user-friendly form building plugin!

53675.5k15](/packages/solspace-craft-freeform)[verbb/navigation

Create navigation menus for your site.

92698.4k18](/packages/verbb-navigation)[verbb/workflow

Enforce multi-step review processes for creating entries.

138123.0k1](/packages/verbb-workflow)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
