{"id":329552,"date":"2026-06-22T20:09:50","date_gmt":"2026-06-22T20:09:50","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/gallop\/"},"modified":"2026-06-22T20:09:37","modified_gmt":"2026-06-22T20:09:37","slug":"gallop","status":"publish","type":"plugin","link":"https:\/\/wordpress.org\/plugins\/gallop\/","author":23502399,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"0.1.1","stable_tag":"0.1.1","tested":"7.0","requires":"6.4","requires_php":"8.1","requires_plugins":null,"header_name":"Gallop","header_author":"Gallop Software","header_description":"A purpose-built REST API for Next.js websites \u2014 fetch a page's post, SEO, and site data in one request, with built-in cookie login support for authenticated front ends.","assets_banners_color":"665c5c","last_updated":"2026-06-22 20:09:37","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"https:\/\/gallop.software\/headless-wordpress","header_author_uri":"https:\/\/gallop.software","rating":0,"author_block_rating":0,"active_installs":0,"downloads":33,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"0.1.1":{"tag":"0.1.1","author":"gallopsoftware","date":"2026-06-22 20:09:37"}},"upgrade_notice":{"0.1.0":"<p>Initial release.<\/p>"},"ratings":[],"assets_icons":{"icon-256x256.png":{"filename":"icon-256x256.png","revision":3582339,"resolution":"256x256","location":"assets","locale":"","width":256,"height":256}},"assets_banners":{"banner-1544x500.png":{"filename":"banner-1544x500.png","revision":3582339,"resolution":"1544x500","location":"assets","locale":"","width":1544,"height":500},"banner-772x250.png":{"filename":"banner-772x250.png","revision":3582339,"resolution":"772x250","location":"assets","locale":"","width":772,"height":250}},"assets_blueprints":{},"all_blocks":[],"tagged_versions":["0.1.1"],"block_files":[],"assets_screenshots":{"screenshot-1.jpg":{"filename":"screenshot-1.jpg","revision":3582339,"resolution":"1","location":"assets","locale":"","width":2600,"height":917},"screenshot-2.jpg":{"filename":"screenshot-2.jpg","revision":3582339,"resolution":"2","location":"assets","locale":"","width":3456,"height":1992},"screenshot-3.jpg":{"filename":"screenshot-3.jpg","revision":3582339,"resolution":"3","location":"assets","locale":"","width":3456,"height":1988},"screenshot-4.jpg":{"filename":"screenshot-4.jpg","revision":3582339,"resolution":"4","location":"assets","locale":"","width":3456,"height":1990}},"screenshots":{"1":"The Gallop REST API in action \u2014 a request to the <code>gallop\/v1<\/code> namespace returning post, SEO, and site data.","2":"Login UI: the headless auth flow signing in against <code>\/gallop\/v1\/auth\/login<\/code> with standard WordPress cookies.","3":"Settings tab: point Gallop at your Next.js production URL and configure proxy IP trust for auth rate limiting.","4":"Post Types tab: register REST-enabled custom post types (no code) and view their slugs and REST endpoints."}},"plugin_section":[],"plugin_tags":[710,181897,141196,211409,23853],"plugin_category":[38],"plugin_contributors":[268407],"plugin_business_model":[],"class_list":["post-329552","plugin","type-plugin","status-publish","hentry","plugin_tags-authentication","plugin_tags-decoupled","plugin_tags-headless","plugin_tags-nextjs","plugin_tags-rest-api","plugin_category-authentication","plugin_contributors-gallopsoftware","plugin_committers-gallopsoftware"],"banners":{"banner":"https:\/\/ps.w.org\/gallop\/assets\/banner-772x250.png?rev=3582339","banner_2x":"https:\/\/ps.w.org\/gallop\/assets\/banner-1544x500.png?rev=3582339","banner_rtl":false,"banner_2x_rtl":false},"icons":{"svg":false,"icon":"https:\/\/ps.w.org\/gallop\/assets\/icon-256x256.png?rev=3582339","icon_2x":"https:\/\/ps.w.org\/gallop\/assets\/icon-256x256.png?rev=3582339","generated":false},"screenshots":[{"src":"https:\/\/ps.w.org\/gallop\/assets\/screenshot-1.jpg?rev=3582339","caption":"The Gallop REST API in action \u2014 a request to the <code>gallop\/v1<\/code> namespace returning post, SEO, and site data."},{"src":"https:\/\/ps.w.org\/gallop\/assets\/screenshot-2.jpg?rev=3582339","caption":"Login UI: the headless auth flow signing in against <code>\/gallop\/v1\/auth\/login<\/code> with standard WordPress cookies."},{"src":"https:\/\/ps.w.org\/gallop\/assets\/screenshot-3.jpg?rev=3582339","caption":"Settings tab: point Gallop at your Next.js production URL and configure proxy IP trust for auth rate limiting."},{"src":"https:\/\/ps.w.org\/gallop\/assets\/screenshot-4.jpg?rev=3582339","caption":"Post Types tab: register REST-enabled custom post types (no code) and view their slugs and REST endpoints."}],"raw_content":"<!--section=description-->\n<p>Gallop is the headless WordPress REST API for Next.js that's FAST and SIMPLE. Keep the WordPress you write in, lose the theme that slows you down \u2014 and ship your whole page from one request.<\/p>\n\n<blockquote>\n  <p>The WordPress editing experience your team already knows, with the speed of a fully decoupled Next.js front end. One endpoint, one response, done.<\/p>\n<\/blockquote>\n\n<p><a href=\"https:\/\/gallop.software\/headless-wordpress\">Visit the Gallop homepage &amp; documentation \u2192<\/a><\/p>\n\n<p>Most headless setups make you stitch together a waterfall of core WordPress REST calls per page \u2014 <code>\/wp\/v2\/posts<\/code>, <code>\/wp\/v2\/media<\/code>, meta, and taxonomy \u2014 then bolt on a JWT layer and an auth service just to log a user in. Gallop replaces all of that.<\/p>\n\n<p><strong>One request. The whole page.<\/strong> Hand Gallop a URI and it returns the post body, an SEO block, and your global site data \u2014 already joined, already resolved, ready to render. <strong>The API is the point:<\/strong> a dedicated, Next.js-shaped REST namespace (<code>\/wp-json\/gallop\/v1<\/code>) so your front-end code stays simple \u2014 one fetch, one response, ready to render.<\/p>\n\n<h4>Why choose Gallop?<\/h4>\n\n<ul>\n<li><strong>One round trip instead of five.<\/strong> Everything a page needs \u2014 <code>post<\/code>, <code>seo<\/code>, and <code>site<\/code> \u2014 in a single response.<\/li>\n<li><strong>No JWT, no API keys, no separate auth service.<\/strong> Cookie-based login is built in and wired to WordPress's own <code>wp_signon()<\/code>.<\/li>\n<li><strong>SEO done for you.<\/strong> With Yoast active, the <code>seo<\/code> block ships search-ready out of the box.<\/li>\n<li><strong>No-code custom post types.<\/strong> Register REST-enabled CPTs from the admin \u2014 no <code>register_post_type()<\/code> boilerplate.<\/li>\n<li><strong>Instant publishing.<\/strong> Publish in WordPress and Gallop revalidates the affected Next.js routes automatically \u2014 no full redeploy.<\/li>\n<li><strong>Framework-agnostic JSON.<\/strong> Next.js is the reference target, but any HTTP client can consume the API.<\/li>\n<li><strong>Keep your workflow.<\/strong> Your editors keep the exact WordPress publishing experience they already rely on.<\/li>\n<\/ul>\n\n<h4>Everything a page needs, in one request<\/h4>\n\n<p>Hand Gallop a URI and it returns the whole page in a single response: the full <code>post<\/code>, its <code>seo<\/code> metadata, and your global <code>site<\/code> data, already joined, already resolved, ready to render. <code>GET|POST \/gallop\/v1\/post<\/code> handles posts and pages, and <code>POST \/gallop\/v1\/category<\/code> does the same for taxonomy archives. No waterfall of <code>\/wp\/v2\/posts<\/code>, <code>\/wp\/v2\/media<\/code>, meta, and taxonomy calls per page \u2014 one round trip instead of five, with no JWT, API keys, or complicated authentication to set up. Your front end stays simple, and your pages load fast.<\/p>\n\n<p>The SEO is done for you. With Yoast active, the <code>seo<\/code> block is populated straight from Yoast's indexables (canonical, meta description, OpenGraph, robots flags, reading time) so every page ships search-ready out of the box. Without Yoast, <code>seo<\/code> comes back as an empty object instead of disappearing, so your front end can check it and fall back to its own defaults.<\/p>\n\n<h4>Login, editing, and cache revalidation, already wired up<\/h4>\n\n<p>https:\/\/vimeo.com\/1200535505<\/p>\n\n<p>Moving off a WordPress template usually means rebuilding everything it gave you for free. Gallop ships with it already done. Cookie-based login is wired into the front end through the Gallop plugin, so editors sign in on your Next.js site with their normal WordPress credentials \u2014 no JWT layer, no separate auth service to stand up, and no API keys to manage.<\/p>\n\n<p>Editing works the way your team already knows. Publish or update a post or page in WordPress and Gallop tells your Next.js site to revalidate the affected routes and clear their cache, so changes and new posts go live instantly with no full redeploy. Login, editing, and cache invalidation are all baked in, so you keep the WordPress workflow your team relies on and still ship a fast Next.js front end.<\/p>\n\n<h4>Settings and custom post types, configured from WordPress<\/h4>\n\n<p>https:\/\/vimeo.com\/1196416170<\/p>\n\n<p>Point Gallop at your Next.js production URL and it 301-redirects public WordPress front-end requests to the matching path on your headless host. Admin, REST API, and previews are left untouched.<\/p>\n\n<p>Register REST-enabled custom post types from the Post Types tab and they're immediately available through the Gallop namespace \u2014 no <code>register_post_type()<\/code> boilerplate, no developer round trip. Core post types are left alone, and content you create survives a deactivate\/uninstall.<\/p>\n\n<h4>Trusted on real production sites<\/h4>\n\n<p>Gallop isn't a proof of concept \u2014 it powers live production sites today:<\/p>\n\n<ul>\n<li><strong>douglasnewby.com<\/strong><\/li>\n<li><strong>cmwelectric.com<\/strong><\/li>\n<li><strong>winx.gallop.software<\/strong><\/li>\n<\/ul>\n\n<p>Every one edits in WordPress and ships a fast Next.js front end \u2014 headless content, real Google rankings and structured data, no theme holding it back, and the same WordPress publishing experience your team already knows.<\/p>\n\n<p><a href=\"https:\/\/gallop.software\/headless-wordpress\">See how Gallop powers headless WordPress \u2192<\/a><\/p>\n\n<h4>REST endpoints<\/h4>\n\n<p>All endpoints live under the <code>gallop\/v1<\/code> namespace.<\/p>\n\n<ul>\n<li><code>GET|POST \/gallop\/v1\/post<\/code> \u2014 Resolve a front-end URI to a post and return <code>post<\/code>, <code>seo<\/code>, and <code>site<\/code> payloads. Accepts <code>uri<\/code> as a parameter.<\/li>\n<li><code>POST \/gallop\/v1\/category<\/code> \u2014 Resolve a category URI to a term and return <code>category<\/code>, <code>seo<\/code>, and <code>site<\/code> payloads.<\/li>\n<li><code>POST \/gallop\/v1\/auth\/login<\/code> \u2014 Cookie-based login for a headless front end. Accepts <code>username<\/code>, <code>password<\/code>, and optional <code>remember<\/code>. Rate-limited per username\/IP.<\/li>\n<li><code>POST \/gallop\/v1\/auth\/logout<\/code> \u2014 Log out the current user.<\/li>\n<li><code>GET  \/gallop\/v1\/auth\/session<\/code> \u2014 Return the current user payload, or <code>{ \"user\": null }<\/code> when not logged in.<\/li>\n<\/ul>\n\n<h4>Login support<\/h4>\n\n<p>Gallop ships with everything a Next.js site needs to authenticate users against WordPress \u2014 no extra plugin, no JWT layer to wire up:<\/p>\n\n<ul>\n<li><strong>Cookie-based login<\/strong> via <code>POST \/gallop\/v1\/auth\/login<\/code>, which calls WordPress's built-in <code>wp_signon()<\/code> and sets the standard auth cookies. A Next.js front end on the same registered domain can then make authenticated requests with credentials included.<\/li>\n<li><strong>Session checks<\/strong> via <code>GET \/gallop\/v1\/auth\/session<\/code>, so your front end can tell whether a visitor is logged in and render accordingly.<\/li>\n<li><strong>Logout<\/strong> via <code>POST \/gallop\/v1\/auth\/logout<\/code>.<\/li>\n<li><strong>Brute-force protection<\/strong> out of the box: five failed attempts per username + client IP within fifteen minutes return HTTP 429 until the window expires, with optional reverse-proxy IP awareness for sites behind Cloudflare or a load balancer.<\/li>\n<\/ul>\n\n<h4>SEO integration<\/h4>\n\n<p>When the <a href=\"https:\/\/wordpress.org\/plugins\/wordpress-seo\/\">Yoast SEO<\/a> plugin is active, the <code>seo<\/code> block in the post and category responses is populated from Yoast's indexable data (canonical, meta description, OpenGraph fields, robots flags, reading time, etc.). Without Yoast, <code>seo<\/code> is returned as an empty object so clients can branch safely.<\/p>\n\n<h4>Action hooks<\/h4>\n\n<ul>\n<li><code>gallop_auth_login_success<\/code> \u2014 fires after a successful REST login. Args: <code>WP_User $user<\/code>, <code>WP_REST_Request $request<\/code>.<\/li>\n<li><code>gallop_auth_login_failed<\/code> \u2014 fires after a failed REST login. Args: <code>string $username<\/code>, <code>WP_REST_Request $request<\/code>.<\/li>\n<li><code>gallop_auth_logout<\/code> \u2014 fires after a REST logout. Args: <code>WP_User $user<\/code>, <code>WP_REST_Request $request<\/code>.<\/li>\n<\/ul>\n\n<h4>Filter hooks<\/h4>\n\n<ul>\n<li><code>gallop_trust_forwarded_ip<\/code> \u2014 filter the boolean controlling whether reverse-proxy IP headers (<code>CF-Connecting-IP<\/code>, <code>X-Forwarded-For<\/code>) are trusted when rate-limiting REST auth. Defaults to the \"Trust proxy IP headers\" setting. Only enable behind a trusted proxy that overwrites these headers, otherwise the per-IP rate limit can be bypassed by spoofing them.<\/li>\n<\/ul>\n\n<h4>Data stored<\/h4>\n\n<ul>\n<li><code>gallop_post_types<\/code> (option) \u2014 your custom post type definitions.<\/li>\n<li><code>gallop_nextjs_production_url<\/code> (option) \u2014 the redirect target, if configured.<\/li>\n<li><code>gallop_trust_forwarded_ip<\/code> (option) \u2014 whether to trust reverse-proxy IP headers when rate-limiting auth (default off).<\/li>\n<li><code>gallop_auth_*<\/code> (transients) \u2014 short-lived login rate-limit counters.<\/li>\n<\/ul>\n\n<h3>Privacy<\/h3>\n\n<p>Gallop does not send any data to external services. All data stays on your WordPress site.<\/p>\n\n<p>The <code>\/gallop\/v1\/auth\/login<\/code> endpoint authenticates users with WordPress's built-in <code>wp_signon()<\/code> and sets the standard WordPress auth cookies. To mitigate brute-force attacks, Gallop temporarily stores failed-login counters in WordPress transients keyed by username and by the requesting IP address. These counters expire automatically (typically within 15 minutes) and are removed on plugin uninstall.<\/p>\n\n<p>No personal data is shared with third parties. No tracking, analytics, or telemetry is performed.<\/p>\n\n<!--section=installation-->\n<ol>\n<li>Upload the <code>gallop<\/code> folder to <code>\/wp-content\/plugins\/<\/code>, or install the ZIP from the Plugins screen.<\/li>\n<li>Activate <strong>Gallop<\/strong> from the Plugins screen.<\/li>\n<li>Point your Next.js front end at <code>https:\/\/your-wp-site.example\/wp-json\/gallop\/v1<\/code> and start fetching <code>post<\/code>, <code>category<\/code>, and <code>auth<\/code> endpoints.<\/li>\n<li>(Optional) Open <strong>Gallop<\/strong> in the admin menu to register custom post types and set your Next.js production URL.<\/li>\n<\/ol>\n\n<p>Requires PHP 8.1 or higher. The plugin will refuse to boot and show an admin notice on older PHP versions.<\/p>\n\n<!--section=faq-->\n<dl>\n<dt id=\"do%20i%20have%20to%20use%20next.js%3F\"><h3>Do I have to use Next.js?<\/h3><\/dt>\n<dd><p>No. Gallop's REST endpoints are framework-agnostic JSON. Next.js is the reference target and the redirect feature is named for it, but any HTTP client can consume the API.<\/p><\/dd>\n<dt id=\"does%20the%20redirect%20break%20the%20wordpress%20admin%20or%20previews%3F\"><h3>Does the redirect break the WordPress admin or previews?<\/h3><\/dt>\n<dd><p>No. The redirect runs on <code>template_redirect<\/code> only, skips any request with a <code>preview=true<\/code> or <code>_wp*<\/code> query parameter, and never touches <code>\/wp-admin<\/code> or <code>\/wp-json<\/code>. Leave the Next.js URL setting blank to disable redirection entirely.<\/p><\/dd>\n<dt id=\"how%20does%20authentication%20work%20for%20the%20headless%20client%3F\"><h3>How does authentication work for the headless client?<\/h3><\/dt>\n<dd><p>\/gallop\/v1\/auth\/login calls <code>wp_signon()<\/code> and sets the standard WordPress auth cookies. A Next.js front end on the same registered domain can then call <code>\/gallop\/v1\/auth\/session<\/code> (or any other authenticated REST endpoint) with credentials included. There is no JWT layer \u2014 cookie auth is intentional.<\/p><\/dd>\n<dt id=\"is%20the%20login%20endpoint%20rate-limited%3F\"><h3>Is the login endpoint rate-limited?<\/h3><\/dt>\n<dd><p>Yes. Five failed attempts per username + client IP within fifteen minutes return HTTP 429 until the window expires. Successful logins clear the counter.<\/p><\/dd>\n<dt id=\"what%20is%20the%20%22trust%20proxy%20ip%20headers%22%20setting%3F\"><h3>What is the \"Trust proxy IP headers\" setting?<\/h3><\/dt>\n<dd><p>By default Gallop uses <code>REMOTE_ADDR<\/code> for the per-IP portion of the login rate limit. If your site sits behind a trusted reverse proxy (Cloudflare, a load balancer, etc.) that overwrites the client-IP headers, enable <strong>Trust proxy IP headers<\/strong> on the Gallop settings screen so <code>CF-Connecting-IP<\/code> \/ <code>X-Forwarded-For<\/code> are used instead. Leave it off on direct-served sites \u2014 turning it on without a trusted proxy lets attackers spoof those headers to bypass the rate limit. The setting can also be overridden in code via the <code>gallop_trust_forwarded_ip<\/code> filter.<\/p><\/dd>\n<dt id=\"do%20i%20need%20yoast%20seo%3F\"><h3>Do I need Yoast SEO?<\/h3><\/dt>\n<dd><p>No. If Yoast is not active the <code>seo<\/code> field in responses is an empty object. With Yoast active, Gallop reads from its indexables to populate canonical, OpenGraph, and robots data.<\/p><\/dd>\n<dt id=\"does%20gallop%20modify%20core%20post%20types%3F\"><h3>Does Gallop modify core post types?<\/h3><\/dt>\n<dd><p>No. Posts, pages, media, and built-in taxonomies are left alone. Only post types you create through the Gallop admin screen are registered by this plugin.<\/p><\/dd>\n<dt id=\"what%20happens%20if%20i%20deactivate%20or%20delete%20the%20plugin%3F\"><h3>What happens if I deactivate or delete the plugin?<\/h3><\/dt>\n<dd><p>Deactivating stops Gallop from registering its post types and REST routes; content created under those post types stays in the database. Deleting the plugin (via the Plugins screen) additionally removes the <code>gallop_post_types<\/code>, <code>gallop_nextjs_production_url<\/code>, and <code>gallop_trust_forwarded_ip<\/code> options plus any leftover login rate-limit transients. Posts authored under your custom post types are intentionally left in place so they survive an uninstall\/reinstall.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>0.1.1<\/h4>\n\n<ul>\n<li>Documentation: expanded the plugin description.<\/li>\n<\/ul>\n\n<h4>0.1.0<\/h4>\n\n<ul>\n<li>Initial release.<\/li>\n<li>Admin UI for registering REST-enabled custom post types.<\/li>\n<li><code>\/gallop\/v1\/post<\/code> and <code>\/gallop\/v1\/category<\/code> endpoints with optional Yoast SEO payloads.<\/li>\n<li>Cookie-based REST auth endpoints (<code>\/auth\/login<\/code>, <code>\/auth\/logout<\/code>, <code>\/auth\/session<\/code>) with per-username\/IP rate limiting.<\/li>\n<li>Optional Next.js production URL redirect for public front-end requests.<\/li>\n<\/ul>","raw_excerpt":"A REST API for headless Next.js sites: a page&#039;s post, SEO, and site data in one request, plus cookie login for authenticated front ends.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/329552","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=329552"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/gallopsoftware"}],"wp:attachment":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=329552"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=329552"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=329552"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=329552"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=329552"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=329552"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}