=== AX Coming Soon ===
Contributors: axplugins
Tags: coming soon, maintenance mode, holding page, under construction, launch
Requires at least: 6.5
Tested up to: 7.1
Requires PHP: 8.1
Stable tag: 1.0.1
License: GPL-2.0-or-later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

A holding page for a site you are still building, with a preview link your client can open without a login.

== Description ==

A holding page and nothing else. One screen, eight settings, no page builder.

Point it at a heading, a sentence or two and an image, switch it on, and the public
sees a holding page while you get on with the build. You keep full access, and so does
your client — they get a link that works without a WordPress login, so you do not have
to hand out credentials or put HTTP authentication in front of the site.

**What it does**

* Serves a self-contained holding page with your heading, message and image.
* Returns `503 Service Unavailable` with `Retry-After` and `X-Robots-Tag: noindex`, and
  serves a `Disallow: /` robots.txt, so an unfinished site does not get indexed.
* Optionally closes the REST API, feeds and sitemaps to the public as well. Without
  that, a holding page hides your pages while the REST API still serves their titles
  and content, and an SEO plugin still publishes a sitemap listing every URL.
* Gives you a preview link to send the client. Opening it once remembers that browser
  for a month. Regenerating the link revokes every link already sent.
* Leaves your login, the block editor, WP-Cron and form plugins alone.

**What it deliberately does not do**

No email capture, no countdown timer, no social icons, no template gallery, no
analytics. It makes **no outbound HTTP requests of any kind** and collects no
telemetry, so nothing about your site leaves your server.

**Honest limitations**

* **Files are not protected.** A direct link to something in your uploads folder still
  works, because serving a file never runs WordPress. Use a server rule if that matters.
* **A real `robots.txt` file in your web root wins** over the one WordPress generates.
  If you have one, edit it yourself.
* Single site only. It is not multisite-aware.
* This is a holding page, not access control. Do not rely on it to protect
  confidential material — that should not be on a public server in the first place.

== Installation ==

1. Install and activate the plugin.
2. Go to **Settings → Coming Soon**.
3. Fill in a heading, a message and an image, then tick **Show the holding page**.
4. Copy the client preview link and send it on.

To lock the state from `wp-config.php` instead, add `define( 'AX_COMING_SOON', true );`.
The constant wins in both directions and the checkbox is disabled while it is set.

== Frequently Asked Questions ==

= Does my client need a login? =

No. Send them the preview link from the settings screen. That is the whole reason this
plugin exists — HTTP authentication and host-level maintenance modes force a second
username and password on the client, and they break WP-Cron and incoming webhooks.

= Why 503 rather than a normal page? =

`503` tells search engines the site is temporarily unavailable and to come back, which
is what keeps a half-built site out of the index. The trade-off is that uptime monitors
and Google Search Console will report the site as down. You can switch it to `200` on
the settings screen.

= Will it break my contact form? =

No. Form endpoints are on their own REST namespaces, and Gravity Forms does not use
REST at all. Your login, the block editor and WP-Cron are also untouched.

= I use a caching plugin. =

The holding page is sent with no-cache headers and sets `DONOTCACHEPAGE`. Exclude the
preview cookie from your page cache, and purge the cache when you switch the holding
page off. The `ax_coming_soon_state_changed` action fires on each change if you want to
hook a purge to it.

= Does the holding page show your branding? =

No. It shows your heading, your message, your image and your colours. Nothing else.

== Screenshots ==

1. The holding page.
2. Settings → Coming Soon.

== Changelog ==

= 1.0.1 =
* The real site, when served to a preview-link holder, is now marked not cacheable. A page cache that could not see the preview cookie could otherwise store it and serve it to the public.
* The state-changed hook now also fires on the first save of a fresh install, which WordPress routes through add_option() rather than update_option().

= 1.0.0 =
* First release.
