Enterprise central site — setup
EnterpriseThe central site is what turns Modern DFFS from a per-form tool into something you govern centrally. It is an ordinary SharePoint site holding a few lists, and every Enterprise-licensed form in your tenant reads from it: shared reusable content, a tenant-wide default theme, global Custom CSS and JavaScript, the managed AI relay, cross-site-collection Related Items, and the central license itself.
This guide covers provisioning it. For authoring and using the content once it exists, see the Reusable Content guide.
There are two routes to the same result — a PowerShell script that does it for you (in two flavours, one of which needs no app registration), or a manual walkthrough that needs no PowerShell at all. Neither is better. Pick whichever suits how your organization works.
1. Before you start
- An Enterprise license. Everything the central site provides is Enterprise-only and is checked on every form load.
- SharePoint Administrator or Global Administrator rights to create the site collection (a site collection administrator is enough for the hub route, or if the site already exists).
- Modern DFFS installed and activated on at least one site.
A single site collection on Enterprise can use the central site perfectly well — it just isn’t worth much for one site. The value starts once several site collections share the same content, branding and license.
2. Where it lives — the tenant site, or a hub
The central location is resolved per site collection, automatically, and you can use either or both:
| Location | When it’s used |
|---|---|
| A connected hubsite | The site is joined to a hub and that hub’s root web has a DFFS_Settings list. The hub then serves every site joined to it. |
Tenant site /sites/ModernDFFS_Central | The site isn’t joined to a DFFS-enabled hub. This is the tenant-wide fallback. |
This is what lets a single division run its own central site without involving the rest of the company — provision the same lists on that division’s hub, and only sites joined to the hub use them. Everything else in the tenant falls back to ModernDFFS_Central. Setting up both is a normal, supported arrangement.
Wherever this guide says /sites/ModernDFFS_Central, read “the central location” — substitute your hub URL if that’s where you’re putting it. More on how resolution works in the Reusable Content guide.
3. Option A — the PowerShell script
The script creates the site collection and everything in it, with all columns and field descriptions in place. It is idempotent: run it again on an existing site and it skips whatever is already there and adds only what’s missing, so it’s safe to re-run after an upgrade or a partial setup.
Getting the scripts. They’re a free download, bundled as
EnterpriseReusableContents.zip— Enterprise files →. That archive holds the central-site scripts and the Related Items queue processor; the AI relay files are alongside it inai-relay.zip.Nothing there is license-gated, because none of it does anything on its own: the scripts create SharePoint lists, and only an Enterprise-licensed form ever reads them. Download them before you buy if you want to see exactly what they’d do to your tenant.
Two versions — pick by what you already have
They are functionally identical: same lists, same columns, same tenant and hub modes, both idempotent. Only the runtime and the sign-in differ.
| Your situation | Use | Why |
|---|---|---|
| No Entra ID app registration, and you’d rather not create one | New-DFFSCentralSite-PS5-WebLogin.ps1 | Signs in through a browser window. No app registration, no ClientId, and Windows PowerShell 5.1 is already on the machine. |
| You already use PnP.PowerShell, or your organization standardizes on PowerShell 7 | New-DFFSCentralSite_PS7.ps1 | Uses the current, supported PnP module. If the ClientId already exists, this is the shorter route. |
| Scripts are off the table entirely | Option B | Same result, no PowerShell. |
Worth knowing before you pick the PS5 route. It relies on the legacy
SharePointPnPPowerShellOnlinemodule and browser-cookie sign-in, both of which are retired and no longer maintained — Microsoft has been steadily tightening this kind of authentication. It is the easier path today and the likelier of the two to stop working. If it fails to connect, switch to the PowerShell 7 script or the manual steps; nothing about your central site depends on which one provisioned it.
PowerShell 5.1 — browser login (no app registration)
Needs Windows PowerShell 5.1 (already on Windows 10/11), the legacy module, and SharePoint or Global Administrator rights:
Install-Module SharePointPnPPowerShellOnline -Scope CurrentUser -Force
.New-DFFSCentralSite-PS5-WebLogin.ps1
A browser window opens for you to sign in — that’s the whole authentication story. Add -HubUrl to target a hub (see below).
PowerShell 7 — app registration
Needs PowerShell 7 (aka.ms/powershell), PnP.PowerShell v2+, SharePoint or Global Administrator rights, and an Entra ID app registration.
If you don’t already have a PnP.PowerShell app registration, create one once, signed in as a tenant admin:
Register-PnPEntraIDApp `
-ApplicationName "PnP PowerShell" `
-Tenant <yourTenant>.onmicrosoft.com `
-DeviceLogin `
-SharePointDelegatePermissions "AllSites.FullControl" `
-GraphDelegatePermissions "Group.ReadWrite.All"
Copy the ClientId (a GUID) it prints, then:
Install-Module PnP.PowerShell -Scope CurrentUser -Force -SkipPublisherCheck
.New-DFFSCentralSite_PS7.ps1 -ClientId "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
What happens when you run it
Either script prompts for two things: your tenant name (the subdomain — contoso for contoso.sharepoint.com) and a site title (press Enter for the default, “DFFS Reusable Content”). Two browser sign-ins follow — one to the SharePoint admin center to create the site, one to the new site to provision its contents. Sign in as a SharePoint or Global Administrator both times.
Targeting a hub instead
.New-DFFSCentralSite-PS5-WebLogin.ps1 -HubUrl "https://contoso.sharepoint.com/sites/DivisionHub"
.New-DFFSCentralSite_PS7.ps1 -ClientId "xxxxxxxx-…" -HubUrl "https://contoso.sharepoint.com/sites/DivisionHub"
In hub mode the script creates nothing and never touches the admin center — the hub must already exist. It connects straight to the hub, warns if that site isn’t actually a registered hub, and provisions into its root web. No console prompts, but one browser sign-in as a site collection administrator of the hub. Run it once without -HubUrl for the tenant fallback and once per hub as needed.
What it creates
| Item | Details |
|---|---|
| Communication site | /sites/ModernDFFS_Central — tenant mode only; hub mode provisions into the existing hub root web |
DFFS_Assets library | Document library holding the shared .js, .css and .html files that central content references |
ReusableContent list | RcType, Content, Active, Description, Category and Dependencies, all with field descriptions |
DFFS_Settings list | The SettingValue column, with its field description |
RI_ProvisioningRequests list | The queue for cross-site-collection Related Items. The script also sets SharePoint’s Item-level Permissions to read and edit own items only, so designers see just their own requests. |
After the script — the parts it deliberately leaves to you
It provisions structure only. It sets no permissions and adds no content, because both are decisions about your organization rather than defaults anyone can guess:
- Grant Read on the central site to everyone who uses DFFS forms (typically an “All staff” group). Without this, their forms silently fall back as if the central site didn’t exist.
- Grant Contribute or Edit to the team that maintains shared content.
- Add items to
ReusableContent— see the Reusable Content guide. - Add any settings you need to
DFFS_Settings— see section 5. - If you’ll use cross-site-collection Related Items, grant Contribute on
RI_ProvisioningRequeststo your form designers.
4. Option B — manual setup
Step 1 — Create the site collection
Create a Communication site (a Team site works too) at exactly this URL:
https://<your-tenant>.sharepoint.com/sites/ModernDFFS_Central
The path
/sites/ModernDFFS_Centralis hardcoded in DFFS — it has to match, spelling and casing included. The site title can be anything. (On a hub you don’t need this step; you’re provisioning onto a site that already exists.)
Step 2 — Create the DFFS_Assets library
A document library named exactly DFFS_Assets. No extra columns are needed.
Don’t skip this one. Every central JavaScript and CSS reference must point at a file in
DFFS_Assets— external and third-party URLs are deliberately rejected — so a central site without this library can hold inline content only, and every URL-based item silently fails to appear in the picker. The scripts create it for you; if you’re building by hand it’s easy to miss.
Step 3 — Create the ReusableContent list
A custom list named exactly ReusableContent, with these columns alongside the built-in Title:
| Column | Type | Notes |
|---|---|---|
RcType | Choice | Values: FormElement, CustomJS, CustomCSS |
Content | Multiple lines of text (plain) | The content body — inline code, or an https:// URL to a file in DFFS_Assets |
Active | Yes/No | Only Yes items appear in the picker. Items created from DFFS default to Yes. |
Description | Multiple lines of text (plain) | Optional. Shown read-only in the Properties panel for FormElement items. |
Category | Single line of text | Optional. Groups and filters items in the picker — keep values consistent (Branding, HR, Finance). Uncategorized items always show. |
Dependencies | Multiple lines of text (plain, 8 lines) | Optional. One HTTPS URL per line, pointing at .js or .css files in DFFS_Assets. Only meaningful for FormElement items — CustomJS and CustomCSS items leave it empty. |
Worth adding field descriptions to
RcType,ContentandDependencies— they are what tells a content maintainer that inline<script>is not supported in a FormElement, and thatCustomJSmust be aDFFS_AssetsURL rather than inline code, and thatDependenciestakes file URLs one per line rather than references to other library items. The script writes these for you; if you’re setting up by hand they’re worth the few minutes.
Step 4 — Create the DFFS_Settings list
A custom list named exactly DFFS_Settings, with one added column:
| Column | Type | Notes |
|---|---|---|
SettingValue | Multiple lines of text (plain) | The value for the setting named in Title |
Each setting is one list item: the Title is the setting name, SettingValue holds the value.
Step 5 — Set permissions
DFFS reads these lists as the visiting user, so everyone who should see shared content needs at least Read on the central site.
- Read for the group containing all DFFS form users.
- Edit or Contribute only for the team maintaining the content.
DFFS checks this automatically and shows the “edit in library” shortcut in the picker only to users who actually have edit rights.
5. DFFS_Settings — the settings DFFS recognizes
Add one item per setting. Title must match exactly, including case.
| Title | What it controls |
|---|---|
DFFS_License | The Enterprise license code, loaded instead of each site’s local DFFS_LICENSE list. One key for the whole tenant. |
AIRelayPath | URL of your own AI relay endpoint. See the Enterprise AI relay setup guide. |
DefaultTheme | A CSS block applied as the tenant-wide form theme. Paste what the Theme Builder generates, including the /* DFFS Theme Start */ and End markers. While this is set, the per-form Theme Builder is replaced by a notice so designers can’t override your branding. |
GlobalCustomJS | JavaScript injected into every form in the tenant, running before any per-form Custom JS. |
GlobalCustomCSS | CSS injected into every form, applied after per-form Custom CSS so it takes precedence. |
DisableUpdateCheck | Turns off the configurator’s new version available notice for the whole tenant, so the configurator no longer reads the published version number from spjsworks.com. Any value other than 0, false, no or off turns it off. Admin › About › Enterprise status shows the current state. See the Architecture & Security overview for exactly what the check does. |
SupportContactName | Name of your internal support contact, shown in license banners. |
SupportContactEmail | Internal support email, rendered as a mailto: link. |
SupportContactURL | Internal support website, rendered as a “Support” link. |
RI_ContributeGroup | Optional. A SharePoint group on the central site. When set, “Process pending requests” breaks inheritance on each new RI_* tracking list and grants that group Contribute. |
The three SupportContact* keys can be set in any combination, and they behave differently from everything else here — they keep working for a centrally-licensed site even after its license stops validating, which is exactly when the banner matters. The Reusable Content guide covers that exception and the license lookup order in full.
6. Cross-site-collection Related Items — the provisioning queue
Skip this section unless you’ll link Related Items across site collections. Within a single site, Related Items needs nothing from the central site at all.
Cross-site link rows can’t live in the target site — the person creating the link often has no write access there. So DFFS keeps them all in one central broker store: a tracking list per participating list, named RI_<encodedWeb>__<rootFolder>, on the central site. A user then needs write access only to those central lists, plus read on the target list.
Creating those tracking lists needs Manage Lists on the central site — which most form designers don’t have. That’s what RI_ProvisioningRequests is for:
- A designer configures a cross-site relation. DFFS works out which tracking lists are needed and checks whether they already exist.
- If they exist, the relation is ready immediately — nothing is queued.
- If one is missing and the designer can’t create it, DFFS doesn’t fail. It writes a
Pendingrow toRI_ProvisioningRequestsand shows the designer a copy-paste spec they can hand to an admin. The relation waits. - An admin processes the queue. The tracking lists are created from the request, the right audience is granted Contribute, and the row is marked
Completed. - Next time anyone opens the form, the check passes and linking works.
Creating the queue by hand
The setup script creates this list for you. If you provisioned the central site manually (Option B) and now want cross-site linking, build it like this — a custom list named exactly RI_ProvisioningRequests:
| Column | Type | Purpose |
|---|---|---|
Title | Single line of text | Short label for the request (built in). |
RequestStatus | Choice — Pending / Completed / Rejected, default Pending | Lifecycle state. |
RequestSpec | Multiple lines of text (plain, unlimited) | Machine-readable JSON written by DFFS — the lists and fields to create. Don’t edit by hand. |
RequestSummary | Multiple lines of text (plain) | Plain-language summary so an admin can review before approving. |
ProcessedNote | Multiple lines of text (plain) | Filled in when the request is processed — created list IDs, or why it was rejected. |
Then set the item-level permissions — this is the step that is easy to miss. Open List settings → Advanced settings → Item-level Permissions and set both to the own items only option: Read items that were created by the user and Create items and edit items that were created by the user.
Without it the list still works, but every form designer sees every other designer’s requests. Users with Full Control on the site see all rows either way — that is how an admin reviews the queue.
Two ways to process the queue
Both do the same thing — create the tracking lists from the queued request and close it off. Pick whichever fits how you work:
| Route | How |
|---|---|
| The DFFS admin UI | “Process pending Related Items provisioning requests” on the central site. No tooling needed — the usual choice. |
| PowerShell | Resolve-DFFSRelatedItemsRequests.ps1, supplied alongside the setup scripts. Useful for processing a backlog in one go, or where provisioning is handled by an ops team on a schedule rather than by hand. |
The script reads each Pending request, creates the tracking lists its spec describes — with the exact columns and the source-identity description the DFFS runtime expects — grants Contribute if you’ve set RI_ContributeGroup, and marks the request Completed. It is idempotent, so a list that already exists is left alone. It needs PowerShell 7, PnP.PowerShell and an Entra ID ClientId (the same prerequisites as the PS7 setup script), plus Manage Lists on the central site.
The script mirrors what the DFFS runtime itself creates. If you’re running a mixed estate, keep it on the same version as your DFFS install rather than reusing an old copy — the tracking-list schema is a contract between the two.
Permissions
| Who | On what | Access |
|---|---|---|
| All form designers | RI_ProvisioningRequests | Contribute — item-level security means they only ever see their own requests |
| Central-site admins | The central site | Full Control / Manage Lists, to create the tracking lists |
| Users who create links | Each RI_* tracking list | Contribute — granted automatically if RI_ContributeGroup names a group, otherwise grant it yourself |
| Anyone viewing linked items | The target lists | Read — normal SharePoint trimming applies; unreadable items show a “no access” placeholder |
One visibility trade-off worth knowing. Anyone who can read a tracking list can see that item X relates to item Y — the IDs and list URLs — even when the items themselves are security-trimmed. That’s inherent to the central broker design; if link existence is itself sensitive, keep those relations within a single site collection.
7. Check that it worked
Open a form configurator on any site that should be reading from the central location:
| Where | What you should see |
|---|---|
| Form Elements tab | A Reusable HTML entry in the add-element callout |
| Custom JS / Custom CSS tabs | An Add from library button (once items of that type exist) |
| The library dialog | Items grouped under “This site” and “Central library” |
| License tab | “License is managed centrally ✓” — once DFFS_License is set |
| AI tab | The Enterprise relay status banner — once AIRelayPath is set |
Failure is silent by design. If the central site is missing or the user can’t reach it, DFFS falls back without showing an error, and any local library keeps working. That’s right for end users — but it does mean a permissions mistake looks identical to “nothing configured yet”, so check Read access first when content doesn’t appear.
8. Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
| No Add from library button | No active items in either library, or the license isn’t Enterprise | Confirm at least one item has Active = Yes; check the license tier |
| A central JS or CSS URL item never appears | The URL doesn’t point at the central DFFS_Assets library | It must start https://<tenant>.sharepoint.com/sites/ModernDFFS_Central/DFFS_Assets/ |
| A site ignores the central license | That site still has its own code in its local DFFS_LICENSE list, which wins | Clear the LicenseCode field on the local item — no need to delete the list |
| Global CSS/JS still applies after a downgrade | The license hasn’t been re-validated since | Reload the form — DFFS re-validates every load and stops applying central settings |
| A Professional site doesn’t pick up central settings | Working as designed — central functionality is Enterprise-only | See Pricing & editions |