Problem | slow SSR responses |
Solution | serve the CSR version on initial request and cache the SSR version on the edge in the background |
Problem | rolling out for everyone is too risky |
Solution | route part of the user traffic to the canary instance using custom logic on the edge |
Problem | Nginx 🌚 |
Solution | Cloudflare Workers! |
nginx.conf
in-memory | ad-hoc caching between requests |
Cache API | a bit more flexible CDN caching |
KV | eventually consistent key-value storage |
D1 | distributed SQLite database |
R2 | S3-like blob storage |
Durable Objects | strong consistency and real-time coordination |
0ms
worldwide)$0.50
per million requests)wrangler.toml
name = "example"
main = "index.js"
compatibility_date = "2023-08-14"
account_id = "<your Cloudflare account ID>"
routes = [
{
pattern = "https://www.example.com/*",
zone_name = "example.com"
}
]
index.js
export default {
async fetch(request, env, ctx) {
return fetch(request)
}
}
$ wrangler login
$ wrangler deploy
index.js
export default {
async fetch(request, env, ctx) {
const url = new URL(request.url)
if (url.pathname === '/hello') {
return new Response('Hello World!')
}
return fetch(request)
}
}
const geo = request.cf || {}
let content = ''
content += `Colo: ${geo.colo}`
content += `Country: ${geo.country}`
content += `City: ${geo.city}`
content += `Latitude: ${geo.latitude}`
content += `Longitude: ${geo.longitude}`
content += `Timezone: ${geo.timezone}`
return new Response(content, {
headers: {
'content-type': 'text/plain;charset=UTF-8'
}
})
const rewriter = new HTMLRewriter().on('span#caption', {
async element (element) {
element.setInnerContent('hello world')
}
})
const response = await fetch(request, {
headers: {
'Content-Type': 'text/html;charset=UTF-8'
}
})
return rewriter.transform(response)
async element (element) {
const code = request.cf?.country || 'GB'
const url = new URL(`${env.HELLO_API_URL}/?cc=${code}`)
const response = await fetch(url)
const data = await response.json()
const hello = data.hello.toLowerCase()
element.setInnerContent(`${hello} world`)
}
async element (element) {
const code = request.cf?.country || 'GB'
let hello = await env.KV.get(`${code}-hello`)
if (!hello) {
const url = new URL(`${env.HELLO_API_URL}/?cc=${code}`)
const response = await fetch(url)
const data = await response.json()
hello = data.hello.toLowerCase()
ctx.waitUntil(env.KV.put(`${code}-hello`, hello))
}
element.setInnerContent(`${hello} world`)
}