Use WordPress as a headless CMS backend for your Bolt.new React frontend by querying the built-in wp-json REST API. The REST API is enabled by default since WordPress 4.7 — no plugins required for basic content. Build an API route in Bolt to proxy requests, fetch posts, pages, and custom post types, and render them in React. No WordPress themes or PHP required.
Build a Headless WordPress Site with Bolt.new
WordPress powers over 43% of all websites on the internet, and its built-in REST API — enabled by default since version 4.7 — makes it an excellent headless CMS backend. Decoupling the WordPress backend from the frontend means your content editors keep the familiar WordPress dashboard while your React frontend gains full design freedom, faster page loads, and modern developer workflows. Bolt.new is an ideal tool for building the React frontend layer of a headless WordPress stack.
The WordPress REST API lives at /wp-json/wp/v2/ on any WordPress site and exposes posts, pages, categories, tags, media, custom post types, and more as JSON. For public content, no authentication is needed — just a GET request to the endpoint. For private posts, drafts, or creating/updating content, WordPress supports Application Passwords (generated per user in the WordPress admin dashboard), which you store server-side in a Next.js API route in Bolt.
For more complex content queries — especially sites using Advanced Custom Fields (ACF) or deeply nested relationships — WPGraphQL is a popular free plugin that adds a /graphql endpoint. This lets you fetch exactly the fields you need in a single request rather than multiple REST calls. Whether you choose REST or GraphQL, the Bolt.new integration pattern is the same: an API route proxies requests to your WordPress installation, React components consume the data, and your content editors never need to touch the frontend codebase.
Integration method
WordPress exposes a REST API at /wp-json/wp/v2/ that requires no special configuration for public content. In Bolt.new you build a Next.js API route that fetches posts, pages, and custom post types from WordPress, handles authentication for private content using Application Passwords, and serves the data to React components. For sites requiring authenticated writes or protected content, the API route stores credentials server-side and never exposes them to the client.
Prerequisites
- A WordPress site (self-hosted or WordPress.com Business plan) running version 4.7 or higher with REST API access
- Your WordPress site URL (e.g., https://yoursite.com) — the REST API is at /wp-json/wp/v2/
- Optional: WordPress Application Password generated in WordPress Users → Your Profile → Application Passwords for authenticated requests
- Optional: WPGraphQL plugin installed and activated if using GraphQL queries
- A Bolt.new account with a new Next.js project open
Step-by-step guide
Verify Your WordPress REST API and Set Up Environment Variables
Verify Your WordPress REST API and Set Up Environment Variables
The WordPress REST API is enabled by default on any WordPress site running 4.7 or later. You can verify it works by opening https://yoursite.com/wp-json/wp/v2/posts in a browser — you should see a JSON array of your recent posts. If you get a 404 error, check that pretty permalinks are enabled in WordPress Settings → Permalinks (select any option other than 'Plain'). For public content (published posts and pages), no credentials are needed. For accessing private content, creating posts, or updating content, you need a WordPress Application Password. Generate one by going to WordPress Admin → Users → Your Profile → Application Passwords → enter a name like 'Bolt App' → click 'Add New Application Password'. Copy the generated password immediately. In your Bolt.new project, create a .env file at the project root. Add WP_API_URL as your full WordPress URL (e.g., https://yoursite.com/wp-json/wp/v2) and optionally WP_APP_USER and WP_APP_PASSWORD for authenticated access. Never use your main WordPress admin password — Application Passwords are separate credentials that can be revoked independently.
1# .env — add to project root2WP_API_URL=https://yoursite.com/wp-json/wp/v23WP_APP_USER=your_wp_username4WP_APP_PASSWORD=xxxx xxxx xxxx xxxx xxxx xxxxPro tip: Test your REST API by visiting /wp-json/wp/v2/posts in a browser before writing any code. If the URL redirects or returns HTML, check that WordPress pretty permalinks are enabled.
Expected result: You see a JSON array of posts when visiting your WordPress REST API URL. Environment variables are saved in the .env file.
Prompt Bolt to Generate the WordPress API Route
Prompt Bolt to Generate the WordPress API Route
Use Bolt's AI chat to generate the server-side API route that proxies WordPress REST API requests. The API route is essential because it keeps any authentication credentials out of client code and handles CORS — direct browser requests to external WordPress sites will often be blocked unless the WordPress site has CORS headers configured. Even for completely public content, routing through your own API route gives you a consistent URL structure, lets you transform the data shape, and makes it easy to add caching later. When you paste the prompt below, Bolt will create a Next.js API route that fetches WordPress posts with support for filtering by category and pagination. After generation, verify the code reads WP_API_URL from process.env (server-side, no NEXT_PUBLIC_ prefix needed). The WordPress REST API supports query parameters including ?per_page=10&page=1 for pagination, ?categories=5 for filtering, ?search=keyword for search, and ?_embed for including related data like featured images and author names inline. The _embed parameter is particularly useful because it eliminates multiple round trips to get featured images — the image URLs are nested inside the _embedded['wp:featuredmedia'] field.
Create a WordPress headless CMS integration in this Next.js project. Build an API route at app/api/wordpress/posts/route.ts that fetches posts from the WordPress REST API using process.env.WP_API_URL. Support query params: page (default 1), per_page (default 10), category (optional category ID). Use the _embed parameter to include featured images and author names inline. If WP_APP_USER and WP_APP_PASSWORD environment variables exist, add Basic authentication to the request using Buffer.from('user:pass').toString('base64'). Return posts with id, title.rendered, excerpt.rendered, slug, date, link, and the featured image URL extracted from _embedded['wp:featuredmedia'][0].source_url.
Paste this in Bolt.new chat
1// app/api/wordpress/posts/route.ts2import { NextRequest, NextResponse } from 'next/server';34interface WPPost {5 id: number;6 title: { rendered: string };7 excerpt: { rendered: string };8 content: { rendered: string };9 slug: string;10 date: string;11 link: string;12 _embedded?: {13 'wp:featuredmedia'?: Array<{ source_url: string; alt_text: string }>;14 author?: Array<{ name: string }>;15 };16}1718export async function GET(request: NextRequest) {19 const apiUrl = process.env.WP_API_URL;20 if (!apiUrl) {21 return NextResponse.json({ error: 'WP_API_URL not configured' }, { status: 500 });22 }2324 const { searchParams } = new URL(request.url);25 const page = searchParams.get('page') || '1';26 const perPage = searchParams.get('per_page') || '10';27 const category = searchParams.get('category');2829 const url = new URL(`${apiUrl}/posts`);30 url.searchParams.set('page', page);31 url.searchParams.set('per_page', perPage);32 url.searchParams.set('_embed', '1');33 if (category) url.searchParams.set('categories', category);3435 const headers: Record<string, string> = { 'Content-Type': 'application/json' };36 if (process.env.WP_APP_USER && process.env.WP_APP_PASSWORD) {37 const creds = Buffer.from(38 `${process.env.WP_APP_USER}:${process.env.WP_APP_PASSWORD}`39 ).toString('base64');40 headers['Authorization'] = `Basic ${creds}`;41 }4243 try {44 const response = await fetch(url.toString(), { headers });45 if (!response.ok) {46 return NextResponse.json(47 { error: `WordPress API error: ${response.status}` },48 { status: response.status }49 );50 }51 const posts: WPPost[] = await response.json();52 const totalPages = response.headers.get('X-WP-TotalPages');53 const total = response.headers.get('X-WP-Total');5455 const normalized = posts.map((post) => ({56 id: post.id,57 title: post.title.rendered,58 excerpt: post.excerpt.rendered,59 slug: post.slug,60 date: post.date,61 featuredImage: post._embedded?.['wp:featuredmedia']?.[0]?.source_url || null,62 author: post._embedded?.author?.[0]?.name || 'Unknown',63 }));6465 return NextResponse.json({ posts: normalized, totalPages, total });66 } catch (error) {67 const message = error instanceof Error ? error.message : 'Unknown error';68 return NextResponse.json({ error: message }, { status: 500 });69 }70}Pro tip: WordPress Application Passwords use a space-separated format (xxxx xxxx xxxx xxxx). Remove the spaces when constructing the Basic auth header, or encode the full string with spaces — both work.
Expected result: Calling /api/wordpress/posts in the Bolt preview returns a JSON array of WordPress posts with normalized fields including title, slug, excerpt, featured image URL, and author name.
Build the Blog Listing and Single Post Pages
Build the Blog Listing and Single Post Pages
With the API route working, prompt Bolt to build the React frontend pages. A headless WordPress blog typically needs at least two pages: a listing page showing post cards and a dynamic detail page rendering the full post content. WordPress post content is returned as raw HTML in the content.rendered field — you render it safely using React's dangerouslySetInnerHTML, which is appropriate here because the HTML comes from your own trusted WordPress installation. The listing page calls /api/wordpress/posts and renders a grid of cards with the title, excerpt (also HTML — strip tags with a regex or use the excerpt.rendered field which is already plain text trimmed to a sentence), featured image, and publication date. The dynamic post page needs its own API route for single post lookup. WordPress supports fetching a post by slug using /wp/v2/posts?slug=your-slug — this returns an array; take the first element. WordPress also paginates content for very long posts; the API returns the content in parts if the post uses the more-page tag. Keep each React component focused and under 200 lines for best results in Bolt. Add the link to /blog in your navigation component after both pages are working.
Build a blog section in this Next.js project using WordPress REST API data. Create a blog listing page at app/blog/page.tsx that fetches from /api/wordpress/posts and displays posts in a responsive card grid. Add a dynamic post page at app/blog/[slug]/page.tsx with a second API route at app/api/wordpress/posts/[slug]/route.ts that fetches a single post by slug (GET /posts?slug=SLUG then take first result). Render the full post HTML content using dangerouslySetInnerHTML in a styled prose container. Add a link from listing to post. Use Tailwind CSS with clean typography. Strip HTML tags from excerpts using a simple regex replace.
Paste this in Bolt.new chat
1// app/blog/[slug]/page.tsx2'use client';34import { useEffect, useState } from 'react';5import { useParams } from 'next/navigation';67interface Post {8 id: number;9 title: string;10 content: string;11 date: string;12 author: string;13 featuredImage: string | null;14}1516export default function BlogPostPage() {17 const { slug } = useParams<{ slug: string }>();18 const [post, setPost] = useState<Post | null>(null);19 const [loading, setLoading] = useState(true);2021 useEffect(() => {22 fetch(`/api/wordpress/posts/${slug}`)23 .then((r) => r.json())24 .then((data) => setPost(data.post))25 .finally(() => setLoading(false));26 }, [slug]);2728 if (loading) return <div className="max-w-3xl mx-auto p-8">Loading...</div>;29 if (!post) return <div className="max-w-3xl mx-auto p-8">Post not found.</div>;3031 return (32 <article className="max-w-3xl mx-auto px-4 py-12">33 {post.featuredImage && (34 <img src={post.featuredImage} alt={post.title} className="w-full h-64 object-cover rounded-xl mb-8" />35 )}36 <h1 className="text-4xl font-bold text-gray-900 mb-4" dangerouslySetInnerHTML={{ __html: post.title }} />37 <div className="text-sm text-gray-500 mb-8">38 {new Date(post.date).toLocaleDateString()} · {post.author}39 </div>40 <div41 className="prose prose-lg max-w-none"42 dangerouslySetInnerHTML={{ __html: post.content }}43 />44 </article>45 );46}Pro tip: WordPress returns HTML content with inline styles and WordPress-specific CSS classes. For clean typography, install the @tailwindcss/typography plugin and apply the prose class to the content wrapper — it handles headings, paragraphs, lists, and blockquotes consistently.
Expected result: The /blog listing page shows WordPress posts in a card grid. Clicking a card navigates to /blog/[slug] which renders the full post content including embedded images.
Add WPGraphQL for Flexible Content Queries
Add WPGraphQL for Flexible Content Queries
The WordPress REST API is excellent for standard post and page queries, but if your WordPress site uses Advanced Custom Fields (ACF), complex taxonomies, menus, or custom post types with relationships, WPGraphQL gives you significantly more flexibility. WPGraphQL is a free plugin that adds a /graphql endpoint to your WordPress site. Install it from the WordPress plugin directory, activate it, then navigate to GraphQL → Settings in your WordPress admin to confirm the endpoint is active. The GraphQL playground at /wp-admin/admin.php?page=graphiql-ide lets you test queries before writing code. A key advantage of WPGraphQL over multiple REST calls is that you can fetch exactly the data you need — including nested ACF fields, menu items, related posts, and taxonomy terms — in a single request. The Bolt API route for GraphQL is straightforward: it accepts a query string in the request body, forwards it to your WordPress /graphql endpoint with the appropriate headers, and returns the response. Keep your GraphQL queries in separate TypeScript constants so Bolt can update them easily without rewriting the API route logic.
Add a WPGraphQL integration to this Next.js project. Create an API route at app/api/wordpress/graphql/route.ts that accepts a POST request with a JSON body containing a 'query' string and optional 'variables' object. Forward the request to process.env.WP_GRAPHQL_URL using a POST request with Content-Type: application/json. If WP_APP_USER and WP_APP_PASSWORD are set, include Basic auth. Return the GraphQL response. Then create a page at app/portfolio/page.tsx that uses this route to fetch a 'portfolio' custom post type — query for the 12 most recent items with their title, slug, featuredImage URI, and a custom 'projectUrl' ACF field. Display them in a 3-column grid.
Paste this in Bolt.new chat
1// app/api/wordpress/graphql/route.ts2import { NextResponse } from 'next/server';34export async function POST(request: Request) {5 const graphqlUrl = process.env.WP_GRAPHQL_URL;6 if (!graphqlUrl) {7 return NextResponse.json({ error: 'WP_GRAPHQL_URL not configured' }, { status: 500 });8 }910 const body = await request.json();1112 const headers: Record<string, string> = {13 'Content-Type': 'application/json',14 };1516 if (process.env.WP_APP_USER && process.env.WP_APP_PASSWORD) {17 const creds = Buffer.from(18 `${process.env.WP_APP_USER}:${process.env.WP_APP_PASSWORD}`19 ).toString('base64');20 headers['Authorization'] = `Basic ${creds}`;21 }2223 try {24 const response = await fetch(graphqlUrl, {25 method: 'POST',26 headers,27 body: JSON.stringify(body),28 });2930 const data = await response.json();31 return NextResponse.json(data);32 } catch (error) {33 const message = error instanceof Error ? error.message : 'Unknown error';34 return NextResponse.json({ error: message }, { status: 500 });35 }36}3738// Example GraphQL query to use from a component:39export const POSTS_QUERY = `40 query GetRecentPosts($first: Int!) {41 posts(first: $first) {42 nodes {43 id44 title45 slug46 date47 excerpt48 featuredImage {49 node {50 sourceUrl51 altText52 }53 }54 author {55 node { name }56 }57 categories {58 nodes { name slug }59 }60 }61 }62 }63`;Pro tip: Use the WPGraphQL IDE plugin alongside WPGraphQL to get an in-browser GraphQL playground at /wp-admin/?page=graphiql-ide. Build and test your queries there before adding them to your Bolt code.
Expected result: The /api/wordpress/graphql route accepts GraphQL queries and returns data from your WordPress WPGraphQL endpoint. The portfolio page renders custom post type items from WordPress.
Deploy to Netlify and Configure Production Environment Variables
Deploy to Netlify and Configure Production Environment Variables
Your headless WordPress React frontend works in Bolt's WebContainer preview because all WordPress API calls are outbound HTTP requests from the server-side API route — outbound calls work perfectly in the WebContainer. When you are ready to share the site publicly, connect your Bolt project to Netlify via Settings → Applications → Netlify → Connect. Bolt will build the Next.js project and deploy it to a *.netlify.app URL. After deployment, go to your Netlify dashboard → Site Configuration → Environment Variables and add WP_API_URL, and if applicable WP_GRAPHQL_URL, WP_APP_USER, and WP_APP_PASSWORD. Trigger a redeploy from the Netlify dashboard for the environment variables to take effect. One important WebContainer note: incoming webhooks from WordPress cannot reach the Bolt preview URL. If your WordPress site uses plugins that send HTTP notifications (like Advanced Custom Fields hooks, WooCommerce order webhooks, or editorial workflow plugins), these webhooks require your deployed Netlify URL. Add your Netlify site URL as a trusted domain in your WordPress plugin settings after deployment. For WordPress.com hosted sites, note that the REST API requires authentication for most endpoints — generate an Application Password in WordPress.com settings.
Add a revalidation webhook endpoint at app/api/wordpress/revalidate/route.ts that accepts a POST request with a secret token in the Authorization header matching process.env.WP_REVALIDATE_SECRET. When called, use Next.js revalidatePath to invalidate the /blog and /blog/[slug] pages so content updates in WordPress are reflected without a full redeploy. Return 200 OK on success.
Paste this in Bolt.new chat
1// app/api/wordpress/revalidate/route.ts2import { NextResponse } from 'next/server';3import { revalidatePath } from 'next/cache';45export async function POST(request: Request) {6 const secret = request.headers.get('x-revalidate-secret');7 if (secret !== process.env.WP_REVALIDATE_SECRET) {8 return NextResponse.json({ error: 'Invalid secret' }, { status: 401 });9 }1011 try {12 const body = await request.json();13 const slug = body?.post?.post_name;1415 // Revalidate the blog listing page16 revalidatePath('/blog');1718 // Revalidate the specific post if slug is provided19 if (slug) {20 revalidatePath(`/blog/${slug}`);21 }2223 return NextResponse.json({ revalidated: true, slug });24 } catch {25 return NextResponse.json({ error: 'Revalidation failed' }, { status: 500 });26 }27}Pro tip: Set WP_REVALIDATE_SECRET in Netlify's environment variables, then configure a WordPress plugin like WP Webhooks to call your /api/wordpress/revalidate endpoint after publishing a post. This gives you on-demand cache invalidation without full redeployments.
Expected result: Your headless WordPress frontend is live on Netlify. Content published in WordPress appears on the deployed site. The revalidation endpoint refreshes cached pages when WordPress posts are updated.
Common use cases
Company Blog with React Frontend
Replace a WordPress theme with a custom React frontend while keeping WordPress as the content backend. Marketing teams continue using the WordPress editor they know, while the React frontend delivers better performance, custom design, and modern UI components that themes cannot easily achieve.
Build a headless WordPress blog in Next.js. Create an API route at app/api/wordpress/posts/route.ts that fetches posts from a WordPress site using the REST API endpoint process.env.WP_API_URL/wp/v2/posts with pagination support. Include title, excerpt, slug, featured image URL, author name, and publish date in the response. Then create a blog listing page at app/blog/page.tsx with a card grid layout and a dynamic post page at app/blog/[slug]/page.tsx that fetches and renders a single post's full content.
Copy this prompt to try it in Bolt.new
Custom Post Type Product Catalog
Use WordPress custom post types and Advanced Custom Fields to manage a product catalog, then display it in a React frontend with filtering, sorting, and search functionality. Content editors add products via WordPress admin while the React frontend handles the presentation layer.
Create a product catalog page in Next.js that fetches data from a WordPress REST API. Build an API route at app/api/wordpress/products/route.ts that fetches a 'products' custom post type from process.env.WP_API_URL/wp/v2/products, including ACF custom fields by adding ?acf_format=standard to the request. Display products in a filterable grid with category tags and a search input that filters client-side.
Copy this prompt to try it in Bolt.new
WPGraphQL Content Dashboard
Use the WPGraphQL plugin to query WordPress content with a single flexible GraphQL request instead of multiple REST calls. Ideal for sites with complex content relationships, custom fields, or deeply nested data structures like menus, taxonomies, and related post connections.
Build a Next.js page that queries WordPress using WPGraphQL. Create an API route at app/api/wordpress/graphql/route.ts that sends a POST request to process.env.WP_GRAPHQL_URL with a GraphQL query body to fetch the 10 most recent posts including their title, slug, excerpt, featuredImage URL, categories, and author name. Display the results in a magazine-style layout with a hero post and a sidebar list.
Copy this prompt to try it in Bolt.new
Troubleshooting
WordPress REST API returns a 404 Not Found error at /wp-json/wp/v2/posts
Cause: WordPress pretty permalinks are set to 'Plain' (default) which disables the REST API routing, or the REST API is disabled by a security plugin.
Solution: Go to WordPress Admin → Settings → Permalinks and select any option other than 'Plain' (Post name is recommended). Save changes. If a security plugin is active, check its settings for an option to disable the REST API and re-enable it. Test by opening /wp-json/wp/v2/posts directly in a browser.
CORS error when calling the WordPress API from a React component
Cause: WordPress does not add CORS headers for arbitrary origins by default, so direct browser-side fetch calls to your WordPress URL fail in the Bolt preview.
Solution: Route all WordPress API calls through your Next.js API route at /api/wordpress/posts rather than calling the WordPress URL directly from client components. The API route runs server-side and is not subject to CORS browser restrictions.
1// Wrong — direct call from client component2const res = await fetch('https://yoursite.com/wp-json/wp/v2/posts');34// Correct — call through your API route5const res = await fetch('/api/wordpress/posts');WordPress Application Password authentication returns 401 Unauthorized
Cause: Application Passwords can be disabled by some hosting providers or security plugins, or the password format in the environment variable includes formatting artifacts.
Solution: Verify Application Passwords are enabled in WordPress Admin → Users → Your Profile → scroll to Application Passwords section. If the section is missing, check for security plugins blocking it (like Wordfence). When storing the password in .env, include it exactly as shown after generation — with or without spaces both work in the Basic auth header when properly base64-encoded.
1// Correct Base64 encoding for WordPress Application Passwords2const creds = Buffer.from(3 `${process.env.WP_APP_USER}:${process.env.WP_APP_PASSWORD}`4).toString('base64');5headers['Authorization'] = `Basic ${creds}`;WordPress webhooks or content update notifications do not reach the Bolt preview
Cause: Bolt's WebContainer runs inside the browser and cannot accept incoming HTTP connections from external services like WordPress webhook plugins.
Solution: Deploy to Netlify or Vercel first to get a stable public URL. Configure WordPress webhook plugins (WP Webhooks, Advanced Custom Fields, WooCommerce) to point at your deployed URL. The Bolt preview URL is not suitable for receiving webhooks because WebContainers do not expose a public-facing HTTP server.
Best practices
- Never expose WP_APP_PASSWORD as a NEXT_PUBLIC_ variable — it must remain server-side in the API route only
- Use WordPress Application Passwords instead of your main admin password — they can be revoked individually without changing your login credentials
- Add _embed to REST API requests to fetch featured images and author data in a single round trip instead of multiple calls
- Use Next.js fetch caching with revalidate intervals (fetch(url, { next: { revalidate: 300 } })) for WordPress content that updates infrequently
- Keep WordPress content as clean HTML and apply consistent typography using the Tailwind CSS prose utility class rather than inline styles
- For multi-author sites, implement per-author API tokens using WordPress's user management rather than sharing a single global application password
- Test all REST API calls in the Bolt WebContainer preview before deploying — outbound WordPress API calls work correctly in development
- For private or draft content, verify the Application Password user has the correct WordPress role — Subscriber accounts cannot read private posts
Alternatives
Ghost is a modern headless CMS purpose-built for publishing with a cleaner REST API and built-in subscription/newsletter features, making it a simpler choice if you do not need WordPress's plugin ecosystem.
Weebly targets non-technical site builders without a developer-facing API, making it a poor choice for headless CMS integrations compared to WordPress's comprehensive REST API.
Joomla has a REST API since version 4.0 but has a smaller headless CMS ecosystem and fewer developer resources than WordPress, though it suits organizations already invested in Joomla.
TYPO3 is an enterprise CMS popular in European markets with a REST API extension, better suited to large-scale enterprise content management than WordPress's typical use cases.
Frequently asked questions
Does Bolt.new work with WordPress?
Yes. WordPress has a built-in REST API at /wp-json/wp/v2/ that works well with Bolt.new's Next.js API routes. You build an API route that proxies WordPress content requests, keeping any authentication credentials server-side. Outbound calls to WordPress work in Bolt's WebContainer preview, so you can develop and test the integration without deploying.
Do I need to install any WordPress plugins to use the REST API?
No plugins are required for the basic WordPress REST API — it is built into WordPress core since version 4.7 and enabled by default. You only need to ensure pretty permalinks are enabled in Settings → Permalinks. The WPGraphQL plugin is optional and only needed if you prefer GraphQL queries over the standard REST API.
Can I use Bolt.new to build a full headless WordPress e-commerce store?
Yes, with the WooCommerce REST API. WooCommerce exposes products, orders, customers, and cart operations through its REST API at /wp-json/wc/v3/. You build API routes in Bolt for each WooCommerce endpoint, using WooCommerce API keys (Consumer Key and Secret) generated in WooCommerce → Settings → Advanced → REST API. Combine with Stripe for payment processing since WooCommerce REST API does not expose payment credentials directly.
How do I handle WordPress content updates in my Bolt.new frontend?
For development, simply refresh the page — API routes fetch fresh content each time. For production, implement Next.js on-demand revalidation: build a webhook endpoint that WordPress calls after publishing, which calls revalidatePath() for the affected pages. Set up a WordPress webhook plugin to call this endpoint with a secret token. This avoids full redeployments while keeping content fresh within seconds of a WordPress publish.
Can I write back to WordPress (create posts, upload media) from Bolt.new?
Yes. The WordPress REST API supports POST, PUT, and DELETE operations for authenticated requests. Use an Application Password stored in your server-side environment variables to authenticate write operations in your API routes. Creating posts uses POST to /wp/v2/posts, uploading media uses POST to /wp/v2/media with multipart form data. Never attempt write operations from client-side React code — always route them through an API route.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation