Common issues and solutions when using NextPress for WordPress content rendering in Next.js.
Common issues and solutions when using NextPress.
1. Check middleware matcher
The proxy only runs for routes in the matcher. Ensure your proxy.ts includes:
export const config = { matcher: [ '/atx/:instance/wp', '/atx/:instance/wc', '/atx/:instance/wp-json/:path*', '/atx/:instance/wp-assets/:path*', '/atx/:instance/wp-internal-assets/:path*', ], };
2. Verify instance configuration
Check that instance slugs in URLs match your withWCR config:
// next.config.mjs export default withWCR(nextConfig, { instances: { default: { wpDomain: 'example.com', wpProtocol: 'https' }, }, // ... });
3. Check WordPress accessibility
Verify WordPress is reachable from your Next.js server:
curl https://your-wordpress.com/wp-json/wp/v2/posts
1. Enable CORS in NextPress settings
Navigate to Settings > NextPress in WordPress admin:
https://mysite.com)2. Include all frontend URLs
Add each frontend URL on a new line:
https://mysite.com
https://www.mysite.com
http://localhost:3000
3. Use CORS filter for dynamic origins
For staging/preview environments:
add_filter('nextpress_cors_allowed_origins', function($origins) { // Add Vercel preview URLs if (isset($_SERVER['HTTP_ORIGIN'])) { $origin = $_SERVER['HTTP_ORIGIN']; if (preg_match('/\.vercel\.app$/', $origin)) { $origins[] = $origin; } } return $origins; });
4. Check WPGraphQL CORS settings
If using WPGraphQL directly (not through proxy), also configure WPGraphQL's CORS settings.
1. Check GraphQL query
Ensure your query includes all script fields:
query GetAssets($uri: String!) { uriAssets(uri: $uri) { scripts { handle src version location strategy dependencies extraData before after } } }
2. Use correct components
WPHead for location: 'HEADER' scriptsWPFooter for location: 'FOOTER' scriptsconst headerScripts = scripts.filter(s => s.location === 'HEADER'); const footerScripts = scripts.filter(s => s.location === 'FOOTER');
3. Check dependency resolution
Scripts with missing dependencies won't load correctly. Verify all dependency handles are included in the scripts array.
1. Check asset proxy routes
Ensure your matcher includes asset routes:
matcher: [ '/atx/:instance/wp-assets/:path*', '/atx/:instance/wp-internal-assets/:path*', ],
2. Verify WordPress URLs
Check wpHomeUrl and wpSiteUrl in your config:
// Standard WordPress { wpDomain: 'example.com', wpProtocol: 'https', } // Bedrock (WordPress in /wp subdirectory) { wpDomain: 'example.com', wpProtocol: 'https', wpHomeUrl: 'https://example.com', wpSiteUrl: 'https://example.com/wp', }
3. Check instance prop
For multi-WordPress setups, ensure components have the correct instance prop:
<Content content={content} instance="blog" />
1. Enable WooCommerce script replacement
In Settings > NextPress, enable "Replace WooCommerce Scripts". This fixes stale nonce issues.
2. Handle Cart-Token
Implement Cart-Token handling in your proxy:
export const proxy = async (request: NextRequest) => { if (isProxiedRoute(pathname)) { // Get Cart-Token from cookies const cartToken = request.cookies.get('cartToken')?.value; if (cartToken) { request.headers.set('Cart-Token', cartToken); } const response = await proxyByWCR(request); // Save updated Cart-Token const updatedCartToken = response.headers.get('Cart-Token'); if (updatedCartToken) { const nextResponse = new NextResponse(response.body, response); nextResponse.cookies.set({ name: 'cartToken', value: updatedCartToken, path: '/', maxAge: 30 * 24 * 60 * 60, httpOnly: true, sameSite: 'lax', }); return nextResponse; } return response; } // ... };
3. Check nonce handling
For authenticated requests, ensure the Authorization header is forwarded.
1. Enable Stripe URL transforms
In Settings > NextPress, enable "Transform Stripe Gateway URLs". This rewrites Stripe URLs to work through the NextPress proxy.
2. Verify WooCommerce Stripe Gateway
Ensure WooCommerce Stripe Gateway is installed and configured.
3. Check HTTPS
Stripe requires HTTPS in production. Ensure your frontend uses HTTPS.
headers().get('x-uri') returns null1. Configure matcher for page routes
Your matcher must include page routes:
export const config = { matcher: [ // WordPress API routes '/atx/:instance/wp', // ... other API routes // Page routes (REQUIRED for x-uri header) '/((?!_next|api|favicon.ico|.*\\.).*)', ], };
2. Set x-uri header in proxy
Ensure your proxy sets the header for non-API routes:
export const proxy = async (request: NextRequest) => { const pathname = request.nextUrl.pathname; if (isProxiedRoute(pathname)) { return proxyByWCR(request); } // Set x-uri for page routes const headers = new Headers(request.headers); headers.set('x-uri', pathname); return NextResponse.next({ request: { headers }, }); };
1. Enable wp-api-fetch replacement
In Settings > NextPress, ensure "Replace wp-api-fetch Script" is enabled (default: on).
2. Check proxy routing
The replaced wp-api-fetch routes requests through your Next.js proxy. Ensure the proxy is configured correctly.
3. Disable if conflicts occur
If you experience conflicts with other plugins, disable the setting and handle API routing manually.
uriAssets returns null1. Verify WPGraphQL is installed
The NextPress plugin requires WPGraphQL 1.27.0+.
2. Check URI format
The URI should be the path without domain:
# Correct uriAssets(uri: "/about") # Incorrect uriAssets(uri: "https://example.com/about")
3. Test in GraphQL IDE
Use the GraphQL IDE in WordPress admin to test queries directly.
For detailed debugging, enable Next.js debug mode:
DEBUG=nextpress:* npm run dev
This logs:
If you're still experiencing issues:
--wp--preset--color--base).text-decoration inside rendered WordPress content match your site chrome instead of the theme's global stylesheet.Tailwind's Preflight layer resets a { color: inherit; text-decoration: inherit }, button { … }, etc., at element-selector specificity. Inside [data-rendered], WordPress's scoped global stylesheet tries to restore theme colors via rules like :where(.wp-element-button) { color: var(--wp--preset--color--base) } — but :where() is zero-specificity, so the Preflight reset wins in some cascade configurations.
Option 1 — Use a dedicated stylesheet for the WordPress route group (recommended).
Split your Tailwind entrypoints: keep globals.css (with full Preflight) for your main layout, and create a wordpress.css that imports Tailwind without Preflight for the (wordpress-pages) layout.
/* app/wordpress.css — Tailwind v4 */ @import "tailwindcss/theme.css" layer(theme); @import "tailwindcss/utilities.css" layer(utilities) important;
The important flag on the utilities import ensures your Tailwind utilities still win over WordPress's scoped global stylesheet inside your app chrome (Navbar, Footer, etc.) without needing Preflight's element resets.
// app/(wordpress-pages)/layout.tsx import "@/app/wordpress.css";
Everything outside the (wordpress-pages) route group continues to import globals.css with full Preflight.
Option 2 — Extend Preflight to skip [data-rendered].
If you need Preflight's resets (for consistency with the rest of your site) but want WordPress content to take over inside [data-rendered], override the offending rules in @layer base:
/* app/globals.css */ @import "tailwindcss"; @layer base { [data-rendered] a { color: revert-layer; text-decoration: revert-layer; } }
revert-layer rolls the declared property back to the value it had before the current cascade layer, effectively removing Preflight's anchor reset for descendants of the NextPress content wrapper and letting WordPress's scoped :where(.wp-element-button) { color: … } rules take effect.
See Tailwind's "Extending Preflight" docs for the underlying technique.
Option 3 — Disable Preflight entirely.
If your project doesn't rely on Preflight at all, use corePlugins.preflight: false (Tailwind v3) or import only the subsets you need (Tailwind v4 — see Option 1). This is the blunt instrument; prefer Option 1 or 2 unless you have a reason to.