PHPackages                             pantheon-systems-ps/pantheon\_nextjs\_multi\_demo - 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. pantheon-systems-ps/pantheon\_nextjs\_multi\_demo

ActiveDrupal-recipe

pantheon-systems-ps/pantheon\_nextjs\_multi\_demo
=================================================

Vertical-agnostic backbone for decoupled Next.js-on-Pantheon demos: content model, JSON:API, OAuth, and the Next.js module wired for per-site association.

1.0.0(today)01↑2900%2GPL-2.0-or-later

Since Jul 28Pushed todayCompare

[ Source](https://github.com/pantheon-systems-ps/pantheon_nextjs_multi_demo)[ Packagist](https://packagist.org/packages/pantheon-systems-ps/pantheon_nextjs_multi_demo)[ RSS](/packages/pantheon-systems-ps-pantheon-nextjs-multi-demo/feed)WikiDiscussions main Synced today

READMEChangelogDependencies (6)Versions (2)Used By (2)

Pantheon Next.js: Global
========================

[](#pantheon-nextjs-global)

Vertical-agnostic backbone for a decoupled Drupal + Next.js architecture on Pantheon. It configures a standard Drupal site as a headless content backend that can serve one or many independent Next.js front ends from a single install.

Apply this recipe first, then apply one or more vertical recipes on top (such as `pantheon_nextjs_edu_demo` or `pantheon_nextjs_commerce_demo`) to register a front end and its content.

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

[](#requirements)

- Drupal core 10.4 or newer.
- The following contrib modules, available via Composer: `drupal/next`, `drupal/decoupled_router`, `drupal/consumers`, `drupal/simple_oauth`, `drupal/pathauto`.

What it configures
------------------

[](#what-it-configures)

- **Modules**: Next.js, Next.js JSON:API, Decoupled Router, Consumers, Simple OAuth, Pathauto, plus the core Datetime and Options modules.
- **Shared content model**: the Page and Article content types with their fields and form/view displays, plus the field storage shared with the vertical event content types.
- **Per-site association**: a `field_next_site` entity-reference field (target type `next_site`, unlimited cardinality) on the shared content types, wired to the Next.js module's `entity_reference_field` site resolver. Each node is tagged with the front end(s) it belongs to and may belong to more than one.
- **Content APIs**: JSON:API for content delivery and the IETF linkset endpoint for decoupled navigation menus.
- **Draft preview**: the Simple OAuth preview generator, plus the `nextjs_preview` role and OAuth scope used to read unpublished content. Complete the one-time setup under [Draft preview](#draft-preview).

This recipe ships no `next_site` entity and no content; those are provided by the vertical recipes.

Apply
-----

[](#apply)

```
composer require pantheon-systems-ps/pantheon_nextjs_multi_demo
drush recipe recipes/pantheon_nextjs_multi_demo
drush cache:rebuild
```

Then apply one or more vertical recipes.

How a front end scopes its content
----------------------------------

[](#how-a-front-end-scopes-its-content)

Each front end filters JSON:API by the `field_next_site` reference:

```
/jsonapi/node/article?filter[field_next_site.meta.drupal_internal__target_id]=edu

```

A front end that omits the filter renders all content: one backend serving everything, or many front ends each serving their own slice.

Draft preview
-------------

[](#draft-preview)

Draft preview lets a front end display unpublished Drupal content. This recipe configures the structural pieces: the Simple OAuth preview generator, the `nextjs_preview` role, and a matching OAuth scope. The remaining pieces carry secrets or are content entities, so complete them once per site as an administrator.

### 1. Generate the OAuth keys

[](#1-generate-the-oauth-keys)

*Configuration &gt; People &gt; Simple OAuth* (`/admin/config/people/simple_oauth`):

- Click **Generate keys**, enter a writable directory outside the web root (a private files path), and confirm. The **Public Key** and **Private Key** fields populate automatically.
- Click **Save configuration**.

If the **Generate keys** button is absent, the PHP OpenSSL extension is disabled. Create an RSA key pair manually and enter the two file paths in the **Public Key** and **Private Key** fields.

### 2. Create the preview service user

[](#2-create-the-preview-service-user)

*People &gt; Add user* (`/admin/people/create`):

- **Username**: `nextjs_preview` (any name works).
- **Status**: Active.
- **Roles**: **Next.js preview**.

This is the account the preview token acts as.

### 3. Configure the default consumer

[](#3-configure-the-default-consumer)

*Configuration &gt; Web services &gt; Consumers* (`/admin/config/services/consumer`), edit **Default Consumer**:

- **Is Confidential?**: checked.
- **Secret**: a value shared with the front end (its `DRUPAL_CLIENT_SECRET`).
- **User**: the `nextjs_preview` user from step 2.
- **Scopes**: **nextjs\_preview**.
- **Grant types**: **Client credentials**.
- **Access token expiration time**: a non-zero value such as **3600**. The default `0` makes tokens expire immediately.

The `nextjs_preview` role and OAuth scope already exist. Select them here; do not recreate them.

### Storing the secret on Pantheon

[](#storing-the-secret-on-pantheon)

Keep the shared secret out of code with [Pantheon Secrets Manager](https://docs.pantheon.io/guides/secrets)(Terminus 4.2+):

```
terminus secret:site:set  nextjs_client_secret "" --type=runtime --scope=web
terminus secret:site:list
```

Read it at runtime in `web/sites/default/settings.php` and apply it when setting the consumer secret:

```
if (function_exists('pantheon_get_secret')) {
  $settings['nextjs_client_secret'] = pantheon_get_secret('nextjs_client_secret');
}
```

Generate the OAuth keys (step 1) into the private files directory. It persists across deploys, while the code directory is read-only on Test and Live.

### Front-end configuration

[](#front-end-configuration)

Each Next.js front end authenticates with the consumer and requests the scope:

```
DRUPAL_CLIENT_ID=default_consumer
DRUPAL_CLIENT_SECRET=
DRUPAL_OAUTH_SCOPE=nextjs_preview
```

Each vertical recipe registers its `next_site` with `preview_url` set to `/api/draft` and `revalidate_url` set to `/api/revalidate`, which the front end implements.

### Verify

[](#verify)

```
curl -s -X POST https:///oauth/token \
  -d grant_type=client_credentials -d client_id=default_consumer \
  -d client_secret= -d scope=nextjs_preview
```

A successful response returns an `access_token` with a non-zero `expires_in`. Then use **Preview** on an unpublished node in Drupal, and the front end enters draft mode and renders it.

###  Health Score

37

—

LowBetter than 81% of packages

Maintenance100

Actively maintained with recent releases

Popularity2

Limited adoption so far

Community10

Small or concentrated contributor base

Maturity33

Early-stage or recently created project

 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

Unknown

Total

1

Last Release

0d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/519297?v=4)[Will Jackson](/maintainers/willjackson)[@willjackson](https://github.com/willjackson)

---

Top Contributors

[![willjackson](https://avatars.githubusercontent.com/u/519297?v=4)](https://github.com/willjackson "willjackson (1 commits)")

### Embed Badge

![Health badge](/badges/pantheon-systems-ps-pantheon-nextjs-multi-demo/health.svg)

```
[![Health](https://phpackages.com/badges/pantheon-systems-ps-pantheon-nextjs-multi-demo/health.svg)](https://phpackages.com/packages/pantheon-systems-ps-pantheon-nextjs-multi-demo)
```

###  Alternatives

[farmos/farmos

A web-based farm record keeping application.

1.3k7.1k1](/packages/farmos-farmos)[govcms/govcms

GovCMS Drupal Distribution

198102.2k3](/packages/govcms-govcms)[voidagency/vactory_starter_kit

Vactory is a custom Drupal profile which is developed and released by VOID Agency.

1021.6k](/packages/voidagency-vactory-starter-kit)

PHPackages © 2026

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