Wrong URL in admin pagination when using CloudFlare Workers for Subdirectory
-
21-04-2021 - |
Question
We implemented a cloudflare worker to serve our subdomain blog blog.domain.com via a subdirectory www.domain.com/blog it's done as described here https://blog.cloudflare.com/subdomains-vs-subdirectories-improved-seo-part-2/
We updated the site settings in WP and all works fine but the pagination in admin is still pointing to the original host which is blog.domain.com
I see similar issues and questions being posted when using a proxy to serve the blog from a special directory, it seems to be no real solution other than modifying the WP core files which I would avoid.
Where is WP pulling the host other than the wp-config.php file?
Solution
With a modified version of the CF Workers, the issue with pagination has been resolved. The idea I found in the comments of the cloudflare post which points to this workers script
addEventListener('fetch', event => {
event.respondWith(handleRequest(event.request))
})
// keep track of all our blog endpoints here
const config = {
hostname: "blog.domain.com",
mainhostname: "www.domain.com",
targetSubdirectory: "/blog",
assetsPathnames: ["/wp-content/", "/wp-includes/"]
}
async function handleRequest(request) {
const parsedUrl = new URL(request.url)
const requestMatches = match => new RegExp(match).test(parsedUrl.pathname)
/**
* Best practice is to only assign new properties on the request
* object (i.e. RequestInit props) through either a method or the constructor
*/
let newRequestInit = {
}
// Change URL
let url = parsedUrl.href.replace(parsedUrl.hostname + config.targetSubdirectory, config.hostname)
if (url.includes('/2020/06/01/some-post') && url[url.length-1] !== '/') {
url = url + '/'
}
// Change just the host
url = new URL(url)
// Best practice is to always use the original request to construct the new request
// thereby cloning all the attributes, applying the URL also requires a constructor
// since once a Request has been constructed, its URL is immutable.
const newRequest = new Request(url, new Request(request, newRequestInit))
try {
return await fetch(newRequest)
} catch (e) {
return new Response(JSON.stringify({ error: e.message }), { status: 500 })
}
}
p.s. there is one line to fix URLs without a slash which did not work with the out of the box script—but we should be able to modify the js code to handle such situations without hardcoding a single URL