WordPress REST API fix
Send X-WP-Nonce for logged-in WordPress REST API requests.
The nonce pattern is for same-origin browser requests made by a logged-in WordPress user. It is not the right auth model for external scripts.
When to use this fix
- A logged-in admin/editor screen calls a REST route from JavaScript.
- The response mentions
rest_cookie_invalid_nonce. - The route works after refresh but fails when the cached page gets old.
- The request is same-origin and should use the WordPress browser session.
When not to use this fix
- Zapier, Make, mobile apps, cron jobs, and server scripts should use Application Passwords or another explicit auth model.
- Public GET endpoints should not require a logged-in nonce unless the data is private.
- Webhooks should use signatures or shared secrets, not a browser nonce.
- Cross-origin frontends need a full auth design, not a copied nonce value.
Before and after JavaScript
Before
fetch('/wp-json/agency/v1/save', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
});
After
fetch(IFK_REST.root + 'agency/v1/save', {
method: 'POST',
credentials: 'same-origin',
headers: {
'Content-Type': 'application/json',
'X-WP-Nonce': IFK_REST.nonce
},
body: JSON.stringify(payload)
});
PHP enqueue pattern
// Pattern to verify in your environment.
add_action('wp_enqueue_scripts', function () {
wp_enqueue_script(
'agency-app',
get_stylesheet_directory_uri() . '/assets/agency-app.js',
[],
'1.0',
true
);
wp_localize_script('agency-app', 'IFK_REST', [
'root' => esc_url_raw(rest_url()),
'nonce' => wp_create_nonce('wp_rest'),
]);
});
Verification checklist
- Confirm the nonce is generated on the page load used for the request.
- Confirm the request includes browser credentials for same-origin cookies.
- Confirm the response is not a cached page with an old nonce.
- Confirm the route still enforces a real capability in
permission_callback.