I was able to resolve the WordPress 6.9 Gutenberg issue and actually it was neither a WordPress bug nor a Gutenberg issue. The root cause was a configuration issue in my .htaccess file.
The Actual Problem
A .htaccess rule enforced trailing slashes and caused 301 redirects if not existent. This was interfering with WordPress REST API endpoints. When the Gutenberg editor attempted to save content via /wp-json/wp/v2/posts/{id} endpoint, the redirect dropped the POST/PUT payload.
The critical insight: I did disable the related WordPress redirect plugin during my initial research, however the .htaccess rule modifications remained unchanged. Deactivating the related WordPress plugin did not ensure the adapted configuration files to be reverted.
Technical Details
The problematic rule:
# BEGIN Force Trailing Slash
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !(.*)/$
RewriteRule ^(.*)$ https://{my TLD}/$1/ [L,R=301]
</IfModule>
# END Force Trailing Slash
What was happening:
- Gutenberg sends POST request to
/wp-json/wp/v2/posts/xxxx?_locale=user - Apache redirects with 301 to
/wp-json/wp/v2/posts/xxxx/?_locale=user(trailing slash added) - The HTTP 301 redirects on POST/PUT requests cause browsers to drop the request body
- Server receives empty request → saves empty post
The Solution
Exclude REST API and admin endpoints from trailing slash redirects:
# BEGIN Force Trailing Slash
<IfModule mod_rewrite.c>
RewriteEngine On
# Exclude wp-json (REST API) and wp-admin from trailing slash redirects
RewriteCond %{REQUEST_URI} !^/wp-json/
RewriteCond %{REQUEST_URI} !^/wp-admin/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !(.*)/$
RewriteRule ^(.*)$ https://{my TLD}/$1/ [L,R=301]
</IfModule>
# END Force Trailing Slash
Verification
After applying the fix:
- REST API requests return http status code
200 OKinstead of301 Moved Permanently - Chrome DevTools Network tab shows no redirects on
/wp-json/endpoints - Content saves correctly in Gutenberg editor
- Request payload reaches the server intact
Key Takeaways
For WordPress admins:
.htaccessrules adadpted by deactivated plugins may persist- Always ensure to also check
.htaccesswhen troubleshooting issues around WordPress REST - be careful when REST API endpoints are redirected with 301/302
- Test configuration changes with browser DevTools Network tab
For debugging:
- Use Chrome DevTools to inspect HTTP requests
- Check both the request payload and response http status codes
- Look at the Initiator tab to understand request origins
- Don’t assume disabled plugins have fully reverted their configuration file changes
Additional Resources
Thanks to the WordPress Gutenberg team for the debugging help and guidance.
Leave a Reply