{"id":6250,"date":"2026-07-13T11:22:06","date_gmt":"2026-07-13T11:22:06","guid":{"rendered":"https:\/\/developer.wordpress.org\/news\/?p=6250"},"modified":"2026-07-13T11:38:02","modified_gmt":"2026-07-13T11:38:02","slug":"on-brand-maintenance-mode-for-wordpress-block-themes","status":"publish","type":"post","link":"https:\/\/developer.wordpress.org\/news\/2026\/07\/on-brand-maintenance-mode-for-wordpress-block-themes\/","title":{"rendered":"On-brand maintenance mode for WordPress Block Themes"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">When WordPress runs updates to core, plugins, or themes it briefly goes into maintenance mode. Visitors are greeted with a plain, unstyled message: <em>&#8220;Briefly unavailable for scheduled maintenance. Check back in a minute.&#8221;<\/em> It works, but it&#8217;s a long way from the polished experience your brand deserves.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For block themes, there&#8217;s a clean solution that splits the work sensibly. First, a hook to the theme. From there, the maintenance page is created and managed entirely in the Site Editor. No file editing, no code, just blocks. Maintenance mode is activated and deactivated in whatever way suits your workflow best.<\/p>\n\n\n\n<div class=\"wp-block-group has-light-grey-2-background-color has-background is-layout-flow wp-block-group-is-layout-flow\" style=\"border-radius:2px;margin-top:var(--wp--preset--spacing--30);margin-bottom:var(--wp--preset--spacing--30);padding-top:var(--wp--preset--spacing--30);padding-right:var(--wp--preset--spacing--30);padding-bottom:var(--wp--preset--spacing--30);padding-left:var(--wp--preset--spacing--30)\">\n<p class=\"has-large-font-size wp-block-paragraph\" style=\"font-style:normal;font-weight:600;line-height:1\">Table of Contents<\/p>\n\n\n\n<nav aria-label=\"Table of Contents\" class=\"wp-block-table-of-contents\"><ol><li><a class=\"wp-block-table-of-contents__entry\" href=\"https:\/\/developer.wordpress.org\/news\/2026\/07\/on-brand-maintenance-mode-for-wordpress-block-themes\/#the-hook\">The hook<\/a><ol><li><a class=\"wp-block-table-of-contents__entry\" href=\"https:\/\/developer.wordpress.org\/news\/2026\/07\/on-brand-maintenance-mode-for-wordpress-block-themes\/#the-minimal-hook-approach\">The minimal hook approach<\/a><\/li><li><a class=\"wp-block-table-of-contents__entry\" href=\"https:\/\/developer.wordpress.org\/news\/2026\/07\/on-brand-maintenance-mode-for-wordpress-block-themes\/#the-seo-friendly-headers-approach\">The SEO-friendly headers approach<\/a><\/li><\/ol><\/li><li><a class=\"wp-block-table-of-contents__entry\" href=\"https:\/\/developer.wordpress.org\/news\/2026\/07\/on-brand-maintenance-mode-for-wordpress-block-themes\/#creating-the-maintenance-template\">Creating the maintenance template<\/a><\/li><li><a class=\"wp-block-table-of-contents__entry\" href=\"https:\/\/developer.wordpress.org\/news\/2026\/07\/on-brand-maintenance-mode-for-wordpress-block-themes\/#activating-and-deactivating-maintenance-mode\">Activating and deactivating maintenance mode<\/a><\/li><li><a class=\"wp-block-table-of-contents__entry\" href=\"https:\/\/developer.wordpress.org\/news\/2026\/07\/on-brand-maintenance-mode-for-wordpress-block-themes\/#testing\">Testing<\/a><\/li><li><a class=\"wp-block-table-of-contents__entry\" href=\"https:\/\/developer.wordpress.org\/news\/2026\/07\/on-brand-maintenance-mode-for-wordpress-block-themes\/#conclusion\">Conclusion<\/a><\/li><\/ol><\/nav>\n<\/div>\n\n\n\n<h2 id=\"the-hook\" class=\"wp-block-heading\">The hook<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Add the following to your theme&#8217;s <code>functions.php<\/code>. This is a one-time task, once it&#8217;s in place, no code changes are needed to manage maintenance mode.<\/p>\n\n\n\n<h3 id=\"the-minimal-hook-approach\" class=\"wp-block-heading\">The minimal hook approach<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">This is fully functional for most sites doing routine update windows:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"php\" class=\"language-php\">\/**\n* Serve the template titled \"Maintenance\" if the template exists.\n*\n* @param string $template The path to the template.\n* @return string The maintenance template path, or the original template.\n*\/\nfunction your_theme_force_maintenance_template( $template ) {\n   if ( is_user_logged_in() ) {\n       return $template;\n   }\n\n   if ( ! current_theme_supports( 'block-templates' ) ) {\n       return $template;\n   }\n\n   \/\/ Look for template(s) titled exactly \"Maintenance\".\n   $maintenance_posts = get_posts(\n       array(\n           'post_type'      =&gt; 'wp_template',\n           'title'          =&gt; 'Maintenance',\n           'post_status'    =&gt; array( 'publish', 'draft' ),\n           'posts_per_page' =&gt; -1,\n           'no_found_rows'  =&gt; true,\n       )\n   );\n\n   $maintenance_post = null;\n\n   foreach ( $maintenance_posts as $post ) {\n       $theme_slugs = wp_get_post_terms( $post-&gt;ID, 'wp_theme', array( 'fields' =&gt; 'names' ) );\n       if ( in_array( get_stylesheet(), $theme_slugs, true ) ) {\n           $maintenance_post = $post;\n           break;\n       }\n   }\n\n   if ( ! $maintenance_post ) {\n       return $template;\n   }\n\n   $slug = $maintenance_post-&gt;post_name;\n\n   return locate_block_template( $template, $slug, array( $slug ) );\n}\nadd_filter( 'template_include', 'your_theme_force_maintenance_template', 99 );\n\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><code>locate_block_template()<\/code> checks for a maintenance template in the right order of precedence, and it checks the database first. That means a template created in the Site Editor will be found, provided it uses the name <code>maintenance<\/code>. Any logged-in user bypasses maintenance mode entirely, so your team can review the live site during an update without hitting the maintenance page.<\/p>\n\n\n\n<figure class=\"wp-block-image alignwide size-full has-custom-border\"><img loading=\"lazy\" decoding=\"async\" width=\"2106\" height=\"1608\" src=\"https:\/\/developer.wordpress.org\/news\/files\/2026\/07\/on-brand-maintenance-frontend.png\" alt=\"Maintenance mode template actively loading for non-logged in users.\" class=\"has-border-color has-light-grey-1-border-color wp-image-6297\" style=\"border-width:1px\" srcset=\"https:\/\/developer.wordpress.org\/news\/files\/2026\/07\/on-brand-maintenance-frontend.png 2106w, https:\/\/developer.wordpress.org\/news\/files\/2026\/07\/on-brand-maintenance-frontend-300x229.png 300w, https:\/\/developer.wordpress.org\/news\/files\/2026\/07\/on-brand-maintenance-frontend-1024x782.png 1024w, https:\/\/developer.wordpress.org\/news\/files\/2026\/07\/on-brand-maintenance-frontend-768x586.png 768w, https:\/\/developer.wordpress.org\/news\/files\/2026\/07\/on-brand-maintenance-frontend-1536x1173.png 1536w, https:\/\/developer.wordpress.org\/news\/files\/2026\/07\/on-brand-maintenance-frontend-2048x1564.png 2048w\" sizes=\"auto, (max-width: 2106px) 100vw, 2106px\" \/><figcaption class=\"wp-element-caption\">An example of a custom maintenance mode template created in Twenty Twentyfour.<\/figcaption><\/figure>\n\n\n\n<h3 id=\"the-seo-friendly-headers-approach\" class=\"wp-block-heading\">The SEO-friendly headers approach<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">If your site has meaningful search traffic or maintenance windows tend to run longer, it&#8217;s worth adding three headers that tell search engine crawlers the downtime is temporary:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"php\" class=\"language-php\">\/**\n* Serve the template titled \"Maintenance\" if the template exists.\n* Includes headers to signal temporary unavailability to search engines.\n*\n* @param string $template The path to the template.\n* @return string The maintenance template path, or the original template.\n*\/\nfunction your_theme_force_maintenance_template( $template ) {\n   if ( is_user_logged_in() ) {\n       return $template;\n   }\n\n   if ( ! current_theme_supports( 'block-templates' ) ) {\n       return $template;\n   }\n\n   \/\/ Look for template(s) titled exactly \"Maintenance\".\n   $maintenance_posts = get_posts(\n       array(\n           'post_type'      =&gt; 'wp_template',\n           'title'          =&gt; 'Maintenance',\n           'post_status'    =&gt; array( 'publish', 'draft' ),\n           'posts_per_page' =&gt; -1,\n           'no_found_rows'  =&gt; true,\n       )\n   );\n\n   $maintenance_post = null;\n\n   foreach ( $maintenance_posts as $post ) {\n       $theme_slugs = wp_get_post_terms( $post-&gt;ID, 'wp_theme', array( 'fields' =&gt; 'names' ) );\n       if ( in_array( get_stylesheet(), $theme_slugs, true ) ) {\n           $maintenance_post = $post;\n           break;\n       }\n   }\n\n   if ( ! $maintenance_post ) {\n       return $template;\n   }\n\n   $slug = $maintenance_post-&gt;post_name;\n\n   $maintenance_template = locate_block_template( $template, $slug, array( $slug ) );\n\n   if ( ! empty( $maintenance_template ) ) {\n       nocache_headers();\n       status_header( 503 );\n       header( 'Retry-After: 3600' );\n       return $maintenance_template;\n   }\n\n   return $template;\n}\nadd_filter( 'template_include', 'your_theme_force_maintenance_template', 99 );\n\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><code>status_header( 503 )<\/code> sends a &#8220;Service Unavailable&#8221; response so crawlers know the downtime is temporary rather than a permanent change. <code>Retry-After: 3600<\/code> suggests they check back in an hour. <code>nocache_headers()<\/code> prevents the response from being stored by CDNs or proxies, so the live site is served immediately once maintenance mode is disabled. None of these affect what visitors see.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Note that in this version the headers are sent inside the template check so they are not being set unless a maintenance template is actually being served.<\/p>\n\n\n\n<h2 id=\"creating-the-maintenance-template\" class=\"wp-block-heading\">Creating the maintenance template<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">With the hook in place, the maintenance page is created entirely in the Site Editor.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Navigate to <strong>Appearance <span aria-hidden=\"true\" class=\"wp-exclude-emoji\">\u2192<\/span> Editor <span aria-hidden=\"true\" class=\"wp-exclude-emoji\">\u2192<\/span> Templates<\/strong> and add a new template. Name it <strong>Maintenance<\/strong>, and WordPress will assign it the slug <code>maintenance<\/code>, which is what the hook is looking for.<\/p>\n\n\n\n<figure class=\"wp-block-image alignwide size-full has-custom-border\"><img loading=\"lazy\" decoding=\"async\" width=\"2978\" height=\"1576\" src=\"https:\/\/developer.wordpress.org\/news\/files\/2026\/07\/on-brand-maintenance-editor.png\" alt=\"A maintenance mode template in the Twenty Twentyfour block theme.\" class=\"has-border-color has-light-grey-1-border-color wp-image-6300\" style=\"border-width:1px\" srcset=\"https:\/\/developer.wordpress.org\/news\/files\/2026\/07\/on-brand-maintenance-editor.png 2978w, https:\/\/developer.wordpress.org\/news\/files\/2026\/07\/on-brand-maintenance-editor-300x159.png 300w, https:\/\/developer.wordpress.org\/news\/files\/2026\/07\/on-brand-maintenance-editor-1024x542.png 1024w, https:\/\/developer.wordpress.org\/news\/files\/2026\/07\/on-brand-maintenance-editor-768x406.png 768w, https:\/\/developer.wordpress.org\/news\/files\/2026\/07\/on-brand-maintenance-editor-1536x813.png 1536w, https:\/\/developer.wordpress.org\/news\/files\/2026\/07\/on-brand-maintenance-editor-2048x1084.png 2048w\" sizes=\"auto, (max-width: 2978px) 100vw, 2978px\" \/><figcaption class=\"wp-element-caption\">Create your maintenance template in the Site Editor just like you would any other template, use patterns, template parts and more.<\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Build it out like any other template. It has full access to your theme&#8217;s Global Styles, so your fonts, colours, and spacing are all available. Include your header and footer template parts for the full site frame, or leave them out for a more focused page. Add a heading, a message, a logo, whatever reflects your brand.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Once saved, the template is stored in the database and the hook will find it automatically.<\/p>\n\n\n\n<div class=\"wp-block-group is-layout-constrained wp-block-group-is-layout-constrained\">\n<h2 id=\"activating-and-deactivating-maintenance-mode\" class=\"wp-block-heading\">Activating and deactivating maintenance mode<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The fastest switch is renaming the template itself. Since the hook checks for a template named <code>maintenance<\/code>, creating it (as described above) turns maintenance mode on. To turn it off, go to <strong>Appearance<\/strong> <span aria-hidden=\"true\" class=\"wp-exclude-emoji\">\u2192<\/span> <strong>Editor<\/strong> <span aria-hidden=\"true\" class=\"wp-exclude-emoji\">\u2192<\/span> <strong>Templates<\/strong>, find the Maintenance template, and rename or delete it \u2014 no file access, code, or configuration needed.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full has-custom-border\"><img loading=\"lazy\" decoding=\"async\" width=\"1750\" height=\"958\" src=\"https:\/\/developer.wordpress.org\/news\/files\/2026\/07\/on-brand-maintenance-templates-1.png\" alt=\"Deactivated maintenance mode in the template browser.\" class=\"has-border-color has-light-grey-1-border-color wp-image-6305\" style=\"border-width:1px\" srcset=\"https:\/\/developer.wordpress.org\/news\/files\/2026\/07\/on-brand-maintenance-templates-1.png 1750w, https:\/\/developer.wordpress.org\/news\/files\/2026\/07\/on-brand-maintenance-templates-1-300x164.png 300w, https:\/\/developer.wordpress.org\/news\/files\/2026\/07\/on-brand-maintenance-templates-1-1024x561.png 1024w, https:\/\/developer.wordpress.org\/news\/files\/2026\/07\/on-brand-maintenance-templates-1-768x420.png 768w, https:\/\/developer.wordpress.org\/news\/files\/2026\/07\/on-brand-maintenance-templates-1-1536x841.png 1536w\" sizes=\"auto, (max-width: 1750px) 100vw, 1750px\" \/><figcaption class=\"wp-element-caption\">Deactivating maintenance mode is as easy as renaming the template.<\/figcaption><\/figure>\n\n\n\n<h2 id=\"testing\" class=\"wp-block-heading\">Testing<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Create the Maintenance template in the Site Editor, then log out and visit the site. You should see your maintenance page. Log back in and confirm the live site loads normally. When you&#8217;re satisfied, delete the template.<\/p>\n<\/div>\n\n\n\n<h2 id=\"conclusion\" class=\"wp-block-heading\">Conclusion<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">A maintenance page is a small detail, but it&#8217;s one visitors notice. The approach here keeps the work where it belongs: a developer adds the hook once and it stays out of the way, while the people responsible for the site&#8217;s content and brand own the maintenance page entirely through the Site Editor. No static files to manage, no code to touch when the message needs updating, just a template that&#8217;s there when you need it and gone when you don&#8217;t.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><em>Props to <a href='https:\/\/profiles.wordpress.org\/sumitsingh\/' class='mention'><span class='mentions-prefix'>@<\/span>sumitsingh<\/a> and <a href='https:\/\/profiles.wordpress.org\/bph\/' class='mention'><span class='mentions-prefix'>@<\/span>bph<\/a> for reviewing this article and offering feedback.<\/em><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Build a branded maintenance mode for WordPress block themes: add one small hook, then manage everything\u2014design and activation\u2014in the Site Editor.<\/p>\n","protected":false},"author":3657560,"featured_media":6314,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"edge","default_image_id":0,"font":"","enabled":false},"version":2},"_wpas_customize_per_network":false,"jetpack_post_was_ever_published":false},"categories":[38],"tags":[102,101],"class_list":["post-6250","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-themes","tag-site-editor","tag-template-parts","mentions-bph","mentions-sumitsingh"],"revision_note":"","jetpack_publicize_connections":[],"jetpack_featured_media_url":"https:\/\/developer.wordpress.org\/news\/files\/2026\/07\/on-brand-maintenance-featured.png","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/developer.wordpress.org\/news\/wp-json\/wp\/v2\/posts\/6250","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/developer.wordpress.org\/news\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/developer.wordpress.org\/news\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/developer.wordpress.org\/news\/wp-json\/wp\/v2\/users\/3657560"}],"replies":[{"embeddable":true,"href":"https:\/\/developer.wordpress.org\/news\/wp-json\/wp\/v2\/comments?post=6250"}],"version-history":[{"count":37,"href":"https:\/\/developer.wordpress.org\/news\/wp-json\/wp\/v2\/posts\/6250\/revisions"}],"predecessor-version":[{"id":6316,"href":"https:\/\/developer.wordpress.org\/news\/wp-json\/wp\/v2\/posts\/6250\/revisions\/6316"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/developer.wordpress.org\/news\/wp-json\/wp\/v2\/media\/6314"}],"wp:attachment":[{"href":"https:\/\/developer.wordpress.org\/news\/wp-json\/wp\/v2\/media?parent=6250"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/developer.wordpress.org\/news\/wp-json\/wp\/v2\/categories?post=6250"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/developer.wordpress.org\/news\/wp-json\/wp\/v2\/tags?post=6250"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}