This guide explains how to preview content from a WordPress backend on a separate headless front end (like a React or Next.js site). You’ll learn the two main approaches—using the WordPress REST API with authentication, or using a service like GraphQL—and how to set up preview links that work for draft and scheduled posts.
What You’ll Need
- A WordPress site (self-hosted or WordPress.com with a business plan) with a headless front end already connected (e.g., via REST API or WPGraphQL).
- Admin access to the WordPress dashboard to install plugins and create application passwords.
- Basic familiarity with your front-end framework (React, Next.js, Vue, etc.) and how to handle routes and API calls.
- For the REST API method: an authentication plugin like “Application Passwords” (core since WordPress 5.6) or a plugin like “JWT Authentication for WP REST API”.
- For the GraphQL method: the WPGraphQL plugin installed and activated.
Step-by-Step
- Decide on your preview strategy. You have two main options: (a) use the WordPress REST API with authentication to fetch draft content, or (b) use WPGraphQL with a preview token. The REST API method is simpler for small sites; GraphQL is better if you already use it for your front end.
- Set up authentication for REST API previews. In your WordPress admin, go to Users → Profile. Scroll to “Application Passwords” (if you don’t see it, install the “Application Passwords” plugin). Create a new application password with a name like “Headless Preview”. Copy the generated password—you’ll only see it once.
- Create a preview endpoint on your front end. In your front-end app, create a route like
/preview/:id(or/preview?id=123). This route will fetch the draft content from WordPress and render it. - Fetch the draft content via the REST API. In that route, make a GET request to
https://yourwpdomain.com/wp-json/wp/v2/posts/{id}?status=draft(or?status=pendingfor pending review). Include an Authorization header:Basic base64(username:application_password)(or use a JWT token if you set that up). The response will include the post content and title. - Render the content. In your front-end component, take the
content.renderedfield and render it as HTML (usingdangerouslySetInnerHTMLin React, orv-htmlin Vue). Style it to match your site. - Add a preview button in WordPress. In your WordPress theme’s
functions.php, add a filter to modify the preview link. For example, to make the preview button point to your headless front end, use thepreview_post_linkfilter. The link should be something likehttps://yourfrontend.com/preview/{post_id}. - For GraphQL method: Install WPGraphQL. In your front end, use a GraphQL query like
query { post(id: "123", idType: DATABASE_ID, asPreview: true) { title, content } }. WPGraphQL returns the preview data if the request is authenticated with a valid token (e.g., using WPGraphQL JWT Authentication). - Handle non-authenticated previews (optional). If you want previews to work for users without login, you can create a temporary preview token in WordPress (e.g., via a custom REST endpoint that generates a nonce) and pass it to your front end. This is more advanced and not strictly necessary for a basic setup.
- Test with a draft post. Create a new post in WordPress, save it as a draft, then click the “Preview” button. It should open your front-end preview page with the draft content.
Common Mistakes
- Not sending authentication headers. Draft posts are private; without a valid token, the REST API returns a 401 error. Ensure your front-end request includes the Authorization header.
- Using the wrong status parameter. For drafts, use
status=draft; for pending review, usestatus=pending. For scheduled posts, usestatus=future. - Forgetting to handle the preview link filter correctly. The
preview_post_linkfilter expects a URL string. If you don’t return a full URL, the preview button may break. - Rendering HTML without sanitization. WordPress content is generally safe, but if you allow user contributions, use a sanitizer to prevent XSS.
- Hardcoding the front-end URL. Use environment variables or a constant to store the front-end URL, so it’s easy to change between staging and production.
Tips
- Use a preview secret. Add a secret query parameter (e.g.,
?preview_secret=your_random_string) to your preview link, and verify it on the front end before fetching. This prevents unauthorized access to drafts. - Cache previews carefully. Don’t use a CDN cache for preview routes; they need to be fresh every time.
- Consider using a headless CMS plugin. Plugins like “Headless CMS” or “WPGraphQL for ACF” can simplify preview handling, but they add complexity.
- Test with different user roles. Ensure that editors and authors can also preview their own drafts, not just admins.
- Use the WordPress preview nonce. For a more secure preview, you can pass a nonce that expires, but that requires custom REST endpoints.
Troubleshooting
- Preview shows 404 on front end. Check that your front-end route matches the preview URL. If using a query parameter, ensure your framework handles it (e.g., in Next.js, use
useRouterto read the query). - REST API returns 401 Unauthorized. Verify your application password is correct and that you’re using Basic Auth or JWT. Also ensure the user has permission to read drafts (they must be an editor or admin).
- GraphQL returns null for preview. Make sure you’re using
asPreview: trueand that the post ID is a database ID, not a URI. Also ensure you’re sending the authentication token in the request headers. - Preview button still points to WordPress. If your
preview_post_linkfilter isn’t working, check that your theme is actually using the filter. Sometimes plugins override it. Add error logging to see if the filter is called. - Content appears unstyled. Your front-end CSS may not match the WordPress content classes. Add a basic stylesheet for common WordPress classes like
.aligncenter,.wp-caption, etc. - Scheduled posts preview shows 404. For future posts, the REST API requires
status=futureand authentication. Also, the post may not be available until the scheduled time—check that your front end handles this.
Frequently Asked Questions
Can I preview without authentication?
Yes, but you’d need to expose the draft publicly, which is insecure. A better approach is to use a preview secret token that your front end verifies before fetching.
Does this work with WordPress.com?
Only with a Business or eCommerce plan that allows plugins and application passwords. Free and Personal plans don’t support these features.
How do I preview revisions?
Use the revision parameter in the REST API: /wp/v2/posts/{id}/revisions/{revision_id}. For GraphQL, use the revisionOf field.
Can I preview custom post types?
Yes, for REST API, use the correct endpoint (e.g., /wp/v2/{post_type}). For GraphQL, use the corresponding query type (e.g., page).
Why does my preview show the published version instead of the draft?
This usually happens when the front end is fetching the post without the status=draft parameter or without authentication. Double-check your API call.
Is there a plugin that does this for me?
Yes, plugins like “Headless Mode” or “WP Headless” offer preview functionality, but they often require a specific front-end setup. The manual method gives you full control.
Related
Method: the standard formula for this calculation, rounded as each result states. See how the calculators work or report an error.
More cards in this drawer
- Campus Tech Innovation Hubs: What They Are
- Poco C51 Airtel Prepaid Locked Variant India?
- Jenkins vs GitHub Actions: Which CI/CD Fits Your Team?
- Turn Off Backup Encryption in iTunes?
- Shared VPS Hosting: Is It Better?
- Disk Defrag Pro: What It Does and Whether You Need It