directus extension for purging CF cache

This commit is contained in:
Will Freeman
2026-02-13 11:16:10 -07:00
parent 0d39af9aa0
commit c71898e1a0
5 changed files with 101 additions and 0 deletions

2
cms/.env.example Normal file
View File

@@ -0,0 +1,2 @@
CF_API_KEY=your_cloudflare_api_key
CF_ZONE_ID=your_cloudflare_zone_id

19
cms/docker-compose.yml Normal file
View File

@@ -0,0 +1,19 @@
services:
directus:
image: directus/directus:11.5.1
ports:
- 8055:8055
volumes:
- ./database:/directus/database
- ./uploads:/directus/uploads
- ./extensions:/directus/extensions
environment:
SECRET: ${DIRECTUS_SECRET}
DB_CLIENT: "sqlite3"
DB_FILENAME: "/directus/database/directus.db"
WEBSOCKETS_ENABLED: "true"
CORS_ENABLED: true
CORS_ORIGIN: true
EXTENSIONS_AUTO_RELOAD: true
CF_API_KEY: ${CF_API_KEY}
CF_ZONE_ID: ${CF_ZONE_ID}

View File

@@ -0,0 +1,3 @@
# Purge Cloudflare Cache Directus Extension
A Directus extension to purge Cloudflare cache when content is updated. This extension listens for content updates and sends a request to the Cloudflare API to clear the cache for the affected URLs.

View File

@@ -0,0 +1,31 @@
{
"name": "purge-cf-cache",
"description": "A Directus extension to purge Cloudflare cache",
"icon": "extension",
"version": "1.0.0",
"license": "UNLICENSED",
"keywords": [
"directus",
"directus-extension",
"directus-extension-hook"
],
"type": "module",
"files": [
"dist"
],
"directus:extension": {
"type": "hook",
"path": "dist/index.js",
"source": "src/index.js",
"host": "^10.10.0"
},
"scripts": {
"build": "directus-extension build",
"dev": "directus-extension build -w --no-minify",
"link": "directus-extension link",
"validate": "directus-extension validate"
},
"devDependencies": {
"@directus/extensions-sdk": "^10.1.0"
}
}

View File

@@ -0,0 +1,46 @@
export default ({ action }, { env }) => {
const { CF_API_KEY, CF_ZONE_ID } = env;
const creds = { CF_API_KEY, CF_ZONE_ID };
action('items.create', async ({ collection, keys }) => {
await purgeCloudflareCache(collection, keys, creds);
});
action('items.update', async ({ collection, keys }) => {
await purgeCloudflareCache(collection, keys, creds);
});
action('items.delete', async ({ collection, keys }) => {
await purgeCloudflareCache(collection, keys, creds);
});
};
async function purgeCloudflareCache(collectionName, ids, creds) {
const baseUrl = `cms.deflock.me/items/${collectionName}`;
const additionalUrls = ids ? ids.map(id => `${baseUrl}/${id}`) : [];
console.log(baseUrl);
console.log(additionalUrls);
const res = await fetch(
`https://api.cloudflare.com/client/v4/zones/${creds.CF_ZONE_ID}/purge_cache`,
{
method: "POST",
headers: {
"Authorization": `Bearer ${creds.CF_API_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
prefixes: [
baseUrl,
...additionalUrls
]
})
}
);
if (res.status >= 200 && res.status < 300) {
console.log(`Cloudflare Cache Purged for updated items in collection: ${collectionName}`);
} else
console.error(res);
}