Excluding files from Cloudflare Pages
Five minutes into rolling my own blog I already appreciate the old one...
For now, I'll probably keep using Claude to take my markdown and generate html and xml to deploy and there are a few specifics to the process that I wanted to capture in a Claude skill.
I thought it made sense to keep this version controlled with the site. Although there's nothing sensitive in it, for completeness I wanted to ensure it wasn't in the Cloudflare Pages deployment.
Spoiler: I ended up just adding it to .gitignore, but learned some interesting things along the way.
There is no .cfignore
Git has .gitignore. Docker has .dockerignore. Surely Cloudflare has .cfignore? It doesn't. Despite community requests, and Claude thinking there is (until being asked to confirm it) ... there's no built-in way to exclude files from a Pages deployment. At this point, since it seems like Pages is going away, it never will.
The build step workaround
So, if you need a file in your repo but not deployed - the solution is to add a build step. Even for a static site with no build process.
After Cluading up a few alternative approaches, using tar was actually one of the cleanest:
mkdir -p dist && tar --exclude='.claude' --exclude='.git' --exclude='dist' -c . | tar -x -C dist
Set your build output directory to dist and you're done.
It's really important to exclude the dist folder, or you end up with recursive duplication (ask me how I know).
The ghost file
One kind of strange thing I leanred ... before I added the build step, I'd already deployed the site a few times with my .claude/settings.json file. After fixing the build, that file was still accessible on the live site.
I deleted all old deployments. Still there. I purged the Cloudflare cache. Still there. It's probably still there now.
Turns out Cloudflare Pages has an "asset preservation cache" that keeps old files around for up to a week, even after they're removed from deployments. There's no way to force-purge it.
This is fine for my harmless settings file. But imagine accidentally deploying an API key or password. You'd have to rotate the credential anyway, but having no way to remove it from the CDN for a week feels like a gap? To be honest I kind of assume I am missing something. Let me know if I am.
Back to that spoiler
If you don't need the file version-controlled, just add it to .gitignore. That's what I ended up doing. The build step is only necessary if you need something tracked in git but excluded from deployment. It worked fine, but I want this to be _really_ simple and foresee a point where only the site gets deployed via some sort of proper build step.
But either way: don't deploy secrets to Pages. You can't force-purge them.