Mainframe: Headless WordPress Theme

Mainframe: Headless WordPress Theme

Mainframe is a free, open source WordPress theme built for developers who use WordPress as a backend CMS and REST API source rather than a public-facing website. It is available now on GitHub.

The Problem With Theming Headless WordPress

Most WordPress themes assume the WordPress install is the website. They ship with typography systems, color palettes, layout templates, and frontend JavaScript that serve no purpose in a headless setup. Developers working API-first either activate a minimal starter theme and fight against its assumptions, or strip a general-purpose theme down to almost nothing.

The other common approach is to install a collection of plugins to handle REST API configuration, login URL hardening, CORS headers, and frontend suppression. That works, but it distributes configuration across multiple plugin settings screens, introduces update dependencies, and leaves no single source of truth for how the WordPress instance behaves.

Mainframe takes a different position. It is a WordPress theme that treats the admin dashboard as the product and the public frontend as an implementation detail. The full wp-admin experience remains intact: posts and pages are created and edited there as normal, the media library works, user management works, and any plugin that operates within the admin panel continues to function regardless of whether it exposes data through the REST API. Nothing about the consuming app changes how WordPress is authored.

What Mainframe Does

REST API

Every registered post type is force-exposed via show_in_rest on activation. An opt-out filter (mainframe_expose_post_type_in_rest) is available for post types that should remain private. Beyond basic exposure, Mainframe adds several fields to every REST response that headless setups almost always need but have to wire up manually.

featured_media_url returns a direct image URL on the post object with no second request to /wp/v2/media/:id needed. featured_media_sizes extends this with a map of every registered image size name to its URL. author_info returns a complete author object inline (id, name, slug, avatar URL, description, and profile URL), eliminating the follow-up request to /wp/v2/users/:idcategories_info returns an array of category objects with id, name, and slug rather than a bare array of IDs. ancestor_ids provides an ordered array of ancestor IDs for hierarchical post types, useful for breadcrumb generation in the consuming app.

/wp-json/mainframe/v1/site endpoint returns a complete site summary in a single call: site name, description, URL, logo, and all navigation menus with their top-level items. Consuming apps that need to render a header or navigation structure can fetch everything they need in one request on load.

CORS is handled via a configurable Access-Control-Allow-Origin header in Mainframe Settings. The field is optional. Leaving it empty keeps the WordPress default behavior.

Public Frontend

The front page is a blank white canvas by default. Through the WordPress Customizer, it optionally displays a logo, headline, short message, and linktree-style link cards populated from navigation menus. Nothing appears until it is configured. This gives the WordPress install a minimal, intentional public face without exposing content meant for the consuming app.

All archive, search, author, and date routes redirect to the front page. Singular posts and pages redirect by default, with a per-post meta box that overrides the site default on a post-by-post basis. The three options per post are: use site default, show content, or redirect to home. The _mainframe_route_behavior value is exposed in the REST API so consuming apps can read it.

Plugin-generated routes and custom rewrite rules are left untouched. Only standard WordPress route types are affected.

Custom Login URL

When a slug is configured in Mainframe Settings, /wp-login.php is blocked and the login form is served at the custom path. All WordPress-generated login, logout, and lost-password URLs are rewritten automatically. No slug is set by default, so /wp-login.php remains active until a slug is saved. The feature requires no plugin and is fully reversible.

Admin Cleanup

Several WordPress admin UI elements that have no relevance in a headless setup are removed. The block editor Preview button is removed because the WordPress frontend is not the consuming app. The classic editor Preview button is filtered out via preview_post_link. Irrelevant Customizer sections are hidden. The Discussion panel is removed from the block editor. Settings > Reading and Settings > Discussion are removed from the admin navigation.

These are cosmetic but meaningful changes. They reduce the surface area of the admin interface to what is actually useful in a headless context.

Featured Image URL Field

A per-post Featured Image URL field appears in both the block editor sidebar and the classic editor. It stores an external image URL that overrides the attached featured image in all REST responses. A preview renders in the native Featured Image panel. Posts that previously used the Featured Image from URL plugin will display their existing images automatically without re-entry.

A site-wide default featured image URL can be set in Mainframe Settings as a fallback for posts with no featured image of any kind.

Deploy Webhook

Mainframe fires a non-blocking HTTP POST to a configured URL whenever a post is published or unpublished. The JSON body contains the event type, post ID, post type, and site URL in the format consumed directly by Vercel, Netlify, and Cloudflare Pages deploy hooks. An optional HMAC-SHA256 signing secret adds an X-Mainframe-Signature header so the receiving service can verify authenticity. A 10-second site-wide cooldown prevents flooding when multiple posts are saved in succession.

Auto-Updates

Mainframe checks the GitHub Releases API every 12 hours and surfaces available updates through the standard WordPress theme update UI in Appearance > Themes. One-click updates install the mainframe.zip attached to the latest release. A version details popup shows the release changelog pulled from GitHub. No plugin is required.

Live REST API Reference

Appearance > REST API Reference is a browseable reference page that introspects the live REST API at render time. Any field added by a plugin or custom code appears automatically. All mainframe/v1 endpoints are documented with their response schemas. For every show_in_rest post type, extra fields registered via register_rest_field are listed with Mainframe or Custom source badges. WordPress core fields are collapsed under a togglable disclosure. Object and array fields show their sub-property shapes inline.

Headless Quick Setup

On first activation, Mainframe runs in safe mode. All WordPress content is publicly accessible at standard URLs. A persistent admin notice links to a Quick Setup card in Mainframe Settings. The card presents five opt-in checkboxes: redirect all public routes to home, discourage search engine indexing, disable comments and pingbacks, use a flat upload folder structure, and set a custom login URL slug. All settings are reversible after setup. Dismissing the admin notice applies nothing.

Requirements and Installation

Mainframe requires WordPress 6.0 or later and PHP 8.0 or later. No build tools, no npm, no external dependencies.

Download the latest release ZIP from GitHub, then install via Appearance > Themes > Add New > Upload Theme in wp-admin. Activate the theme and follow the Quick Setup notice to configure headless defaults.

Source code is available at github.com/ConnorOnTheWeb/mainframe-wp-theme.

RSS Feed Newsletter
Contact us

Latest Blog Posts