{"id":11195,"date":"2026-05-27T19:29:52","date_gmt":"2026-05-27T11:29:52","guid":{"rendered":"https:\/\/aeosub.com\/secure-draft-preview-links\/"},"modified":"2026-05-27T19:29:52","modified_gmt":"2026-05-27T11:29:52","slug":"secure-draft-preview-links","status":"publish","type":"post","link":"https:\/\/aeosub.com\/zh\/secure-draft-preview-links\/","title":{"rendered":"Secure Draft Preview Links"},"content":{"rendered":"<div class=\"post-img\" style=\"margin-bottom: 25px\"><img decoding=\"async\" src=\"https:\/\/ps.w.org\/secure-draft-preview-links\/assets\/banner-1544x500.png?rev=3550514\" alt=\"Secure Draft Preview Links\" style=\"width: 100%;height: auto;border-radius: 12px\"><\/div>\n<div class=\"plugin-info-card\" style=\"border: 1px solid #e2e8f0;border-radius: 10px;overflow: hidden;margin-bottom: 30px;font-family: -apple-system, system-ui, sans-serif;background: #fff\">\n<table style=\"width: 100%;border-collapse: collapse;font-size: 14px\">\n<tr style=\"border-bottom: 1px solid #edf2f7\">\n<th style=\"padding: 15px 20px;text-align: left;width: 35%;color: #4a5568;background: #fcfcfc\"><img decoding=\"async\" src=\"https:\/\/ps.w.org\/secure-draft-preview-links\/assets\/icon-256x256.png?rev=3550514\" style=\"width: 40px;height: 40px;border-radius: 6px;margin-right: 12px;vertical-align: middle\"> Developer<\/th>\n<td style=\"padding: 15px 20px;font-weight: 500\"><a href=\"https:\/\/profiles.wordpress.org\/savedprompt\/\" target=\"_blank\" rel=\"noopener\">savedprompt<\/a><\/td>\n<\/tr>\n<tr style=\"border-bottom: 1px solid #edf2f7\">\n<th style=\"padding: 12px 20px;text-align: left;color: #4a5568;background: #fcfcfc\">Version<\/th>\n<td style=\"padding: 12px 20px\">v1.0.0<\/td>\n<\/tr>\n<tr style=\"border-bottom: 1px solid #edf2f7\">\n<th style=\"padding: 12px 20px;text-align: left;color: #4a5568;background: #fcfcfc\">Active Installs<\/th>\n<td style=\"padding: 12px 20px\">0 +<\/td>\n<\/tr>\n<tr style=\"border-bottom: 1px solid #edf2f7\">\n<th style=\"padding: 12px 20px;text-align: left;color: #4a5568;background: #fcfcfc\">Requires \/ Tested<\/th>\n<td style=\"padding: 12px 20px\">6.5 \/ 6.9.4<\/td>\n<\/tr>\n<tr style=\"border-bottom: 1px solid #edf2f7\">\n<th style=\"padding: 12px 20px;text-align: left;color: #4a5568;background: #fcfcfc\">Last Updated<\/th>\n<td style=\"padding: 12px 20px\">2026-05-27 11:02am GMT<\/td>\n<\/tr>\n<tr>\n<th style=\"padding: 12px 20px;text-align: left;color: #4a5568;background: #fcfcfc\">Official Link<\/th>\n<td style=\"padding: 12px 20px\"><a href=\"https:\/\/wordpress.org\/plugins\/secure-draft-preview-links\/\" target=\"_blank\" style=\"text-decoration: none;color: #4a3bca;font-weight: bold\" rel=\"noopener\">View Details \u2192<\/a><\/td>\n<\/tr>\n<\/table><\/div>\n<div class=\"plugin-short-desc\" style=\"margin: 20px 0;padding: 12px 15px;background: #f9fafb;border-left: 4px solid #4a3bca;border-radius: 6px;font-style: italic;color: #4a5568\">Share draft posts with anyone via a secure, time-limited preview link \u2014 no login required.<\/div>\n<p><strong>Secure Draft Preview Links<\/strong> lets you generate a cryptographically secure, unguessable link for any draft post so that people without a WordPress account can read it before it goes live.<\/p>\n<h4>How it works<\/h4>\n<ol>\n<li>Open any draft post or page in the editor.<\/li>\n<li>Check <strong>Enable public preview<\/strong> in the Publish panel (Classic Editor) or Status &amp; Visibility panel (Block Editor).<\/li>\n<li>Copy the generated link and share it with anyone.<\/li>\n<li>The recipient can view the draft without logging in.<\/li>\n<li>Uncheck the box or set the expiry to <strong>Expired<\/strong> to revoke access immediately.<\/li>\n<\/ol>\n<h4>Editor features<\/h4>\n<ul>\n<li>Works with both the <strong>Classic Editor<\/strong> and the <strong>Block Editor<\/strong> (Gutenberg).<\/li>\n<li>Checkbox to enable \/ disable preview \u2014 shown even on auto-draft posts (disabled with a &#8220;save first&#8221; hint).<\/li>\n<li>When a post is published the checkbox automatically disables and shows &#8220;Not available for published posts&#8221;.<\/li>\n<li>Preview URL displayed in a monospace code box \u2014 horizontally scrollable, click to select all.<\/li>\n<li><strong>Copy<\/strong> button and <strong>Open preview<\/strong> button inline with the URL box.<\/li>\n<li><strong>Generate new link<\/strong> button \u2014 invalidates the old link immediately, with a confirmation step before firing.<\/li>\n<li><strong>Stop sharing<\/strong> confirmation bar \u2014 shown when unchecking the checkbox, requires explicit confirmation before removing the link.<\/li>\n<li>Expiry selector with four options:\n<ul>\n<li><strong>48 hours<\/strong> \u2014 default, shows exact time remaining (e.g. &#8220;Expires on: Apr 29 \u00b7 14:32 (4h 12m remaining)&#8221;).<\/li>\n<li><strong>Always available<\/strong> \u2014 link never expires.<\/li>\n<li><strong>Custom time<\/strong> \u2014 set Days, Hours, and Minutes; live &#8220;Expires on:&#8221; display updates as you type; shows error if all fields are cleared without saving.<\/li>\n<li><strong>Expired (disable now)<\/strong> \u2014 immediately invalidates the link without deleting the token.<\/li>\n<\/ul>\n<\/li>\n<li>Expiry settings auto-save on change with a &#8220;Expiry setting saved.&#8221; confirmation message.<\/li>\n<li>Block Editor: snackbar notices for every action (enable, disable, copy, generate new link).<\/li>\n<li>Block Editor: <strong>Open public preview<\/strong> item added to the Preview dropdown (WordPress 6.7+).<\/li>\n<\/ul>\n<h4>Preview Links admin page<\/h4>\n<ul>\n<li>Dedicated <strong>Preview Links<\/strong> menu item in the WordPress admin sidebar.<\/li>\n<li>Two tabs: <strong>Active<\/strong> and <strong>Expired<\/strong>, each showing a count badge.<\/li>\n<li><strong>Paginated table<\/strong> \u2014 20 items per page, with top and bottom pagination controls.<\/li>\n<li>Per-row columns: Post title, Post type, Exact expiry time, Preview URL, Share buttons, Actions.<\/li>\n<li><strong>Copy URL<\/strong> and <strong>Open preview<\/strong> icon buttons inline with the URL.<\/li>\n<li><strong>Share buttons<\/strong>: Facebook, X (Twitter), LinkedIn, Email \u2014 captions include the post title and expiry time (omitted for never-expires links).<\/li>\n<li><strong>Regenerate<\/strong> button \u2014 generates a new token with a confirmation dialog; old link stops working immediately.<\/li>\n<li><strong>Stop Sharing<\/strong> button \u2014 removes the token with a confirmation dialog.<\/li>\n<li><strong>Edit Post<\/strong> link opens in a new tab.<\/li>\n<li>Confirmation dialogs use an inline modal (no browser <code>confirm()<\/code>) with clear messaging about consequences.<\/li>\n<li>Toast notifications slide up from the bottom-right on every action.<\/li>\n<\/ul>\n<h4>Security<\/h4>\n<ul>\n<li>Tokens are 64-character cryptographically random hex strings generated with <code>random_bytes()<\/code>.<\/li>\n<li>Token validation uses <code>hash_equals()<\/code> to prevent timing attacks.<\/li>\n<li>Expired links return a <strong>410 Gone<\/strong> HTTP response.<\/li>\n<li>Invalid tokens return a <strong>403 Forbidden<\/strong> HTTP response.<\/li>\n<li>Preview link is automatically removed when a post is published, made private, or trashed.<\/li>\n<li>All AJAX endpoints are protected with nonces and capability checks.<\/li>\n<li>No data is exposed to unauthenticated users beyond the post content itself.<\/li>\n<\/ul>\n<h4>Post list table<\/h4>\n<ul>\n<li><strong>Public Preview<\/strong> badge shown next to post titles that have an active preview link.<\/li>\n<li><strong>Public Preview<\/strong> filter view in the post list table to quickly find all posts with active links.<\/li>\n<\/ul>\n<h4>Technical<\/h4>\n<ul>\n<li>Works with all viewable public post types (posts, pages, and custom post types).<\/li>\n<li>Pagination links on multi-page posts are rewritten to include the preview token.<\/li>\n<li>Token meta is registered with the REST API for block editor compatibility.<\/li>\n<li>No external dependencies \u2014 pure PHP, jQuery (Classic Editor), and WordPress&#8217;s own React\/wp-components (Block Editor).<\/li>\n<\/ul>","protected":false},"excerpt":{"rendered":"<p>Share draft posts with anyone via a secure, time-limited preview link \u2014 no login required.<\/p>","protected":false},"author":1,"featured_media":9317,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"inline_featured_image":false,"footnotes":""},"categories":[252],"tags":[836,1744,2274,2275,2276,555],"class_list":["post-11195","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-trends","tag-draft","tag-preview","tag-preview-link","tag-public","tag-share","tag-wordpress-plugin"],"_links":{"self":[{"href":"https:\/\/aeosub.com\/zh\/wp-json\/wp\/v2\/posts\/11195","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/aeosub.com\/zh\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/aeosub.com\/zh\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/aeosub.com\/zh\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/aeosub.com\/zh\/wp-json\/wp\/v2\/comments?post=11195"}],"version-history":[{"count":0,"href":"https:\/\/aeosub.com\/zh\/wp-json\/wp\/v2\/posts\/11195\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/aeosub.com\/zh\/wp-json\/wp\/v2\/media\/9317"}],"wp:attachment":[{"href":"https:\/\/aeosub.com\/zh\/wp-json\/wp\/v2\/media?parent=11195"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/aeosub.com\/zh\/wp-json\/wp\/v2\/categories?post=11195"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/aeosub.com\/zh\/wp-json\/wp\/v2\/tags?post=11195"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}