Divine

Multisite

View as Markdown

Multisite is a first-class surface in Divine, not a special case bolted onto a single-site product. On a single-site install Divine lives in the normal admin and treats the one active theme as the workspace. On a multisite network it moves to network admin and treats every network site as its own app, keyed by blog_id. The model is the same in both places: an app is a theme you build inside. Multisite only changes how many apps there are and which capability gates them.

Single Site Versus Multisite

Divine detects the install type with is_multisite() and registers exactly one admin surface for it. The detection is automatic; you do not configure a mode.

On a single-site install, Divine registers under the normal admin menu, gates on manage_options, and hides the multi-app sidebar because there is only one app to build. The active theme is that single app.

On a multisite network, Divine registers under the network admin menu, gates on manage_network, and shows the multi-app sidebar listing the network’s sites. Divine deliberately registers on only one of the two surfaces: on multisite it bails out of the normal per-site admin so the workspace lives in network admin alone, where managing themes across the network belongs.

Aspect Single site Multisite
Admin location Normal wp-admin Network admin
Management capability manage_options manage_network
Multi-app sidebar Hidden Visible
Apps The one active theme One per network site
Create-app action Hidden Links to native site creation

Because the capability differs, an account that can open Divine on a single-site install will not necessarily see it on a network. Reaching the network admin workspace requires manage_network, which is the super admin capability, so the people who manage themes across the whole network are the ones who reach Divine there.

One Site Is One App

On a network, each site is one Divine app, and that app is the site’s active theme. Divine builds the app list from get_sites(), so the sidebar reflects the real network rather than a separate Divine-owned list of workspaces. Adding a site to the network adds an app; the list stays in step with WordPress.

Each app has a stable slug derived from the site’s blog_id:

site-{blog_id}

So blog_id 1 is the app site-1, blog_id 5 is site-5, and so on. The app carries the site’s active stylesheet, its template, a label drawn from the site’s name (falling back to the theme name), and the site’s domain and path. The label and domain are presentation; the blog_id is identity. Two sites running the same theme are still two distinct apps because they have different blog IDs.

blog_id Is Part Of Every Operation

On multisite, blog_id is woven through the workspace, not just the app list. It is part of the workspace identity, the preview session, the signed preview token, and the deploy target. Every Divine action that touches a theme on a network resolves which site it is acting on first, then operates inside that site’s context.

This matters most for deploy. Deploy promotes accepted worktree files into an app theme, and on multisite it targets the selected site’s active theme only. It never fans out across the network and never touches another site’s theme, even when several sites share the same stylesheet name. Deploy remains files-only here as everywhere in Divine: it mirrors theme files and never copies posts, options, uploads, or any database state between sites.

Previews are scoped the same way. A signed preview renders a theme for one request against one site’s data, and the token is bound to that site. A preview issued for one network site does not render against another site’s content.

Per-site behavior like this lives in Divine’s own app and runtime plumbing rather than in the shared preview service-worker kit, so that adding a site or switching the targeted blog stays a Divine concern and does not push network-specific logic into shared code.

Divine Does Not Create Sites

Divine links to WordPress’s own site creation; it is not a hosting product or a custom site provisioner. On a network the create-app action opens the native network admin Add New Site screen rather than running a Divine-specific provisioning flow. You create and configure network sites through WordPress, assign each one a theme, and Divine then surfaces each site as an app you can build. Divine owns the theme workspace, and WordPress owns the network.

Resolving A Site From The CLI

The dv show command builds capturable render URLs, and on a network it has to know which site it is rendering against. It resolves the target subsite in one of three ways.

When exactly one network site runs the theme you are working in, dv show resolves that site automatically from the theme path. You do not have to name a site when the mapping is unambiguous.

When the theme is ambiguous, or you want a specific site, name it explicitly. Pass --site with a slug or numeric blog ID, or pass --url with the site’s URL. The two are mutually exclusive; use one or the other.

dv show page home --site 5
dv show page home --site site-5
dv show page home --url https://network.example/team-blog/

If the named site is not part of the network, dv show reports that the network site was not found rather than rendering against the wrong place. Passing --site on a single-site install is rejected, because there is no network to select from. When you do not name a site and the theme maps cleanly to one, automatic resolution handles it; when it does not, naming the site keeps the render unambiguous.

For the broader set of dv show resolution problems, including running outside a WordPress context and the database-connection failures common to local stacks, see Operations and Troubleshooting.