A modern web dashboard for managing Cloudflare D1 databases! β‘
- β Execute SQL Queries
- β View Table Structures
- β Monitor Database Metrics
- β Dark Mode Interface
- β Real-time Updates
- Fork this repository
- Go to Cloudflare Pages
- Connect your forked repo
- Set build settings:
Framework preset: Next.js
Build command: npx @cloudflare/next-on-pages
Build output directory: .vercel/output/static
- Log in to Cloudflare Dashboard
- Find in right sidebar or URL:
https://dash.cloudflare.com/<Account ID>
Create token with permissions:
D1: Read & Write
Workers Scripts: Read & Write
- Go to Workers & Pages
- Create new Worker
- Just Paste code:
addEventListener('fetch', event => {
event.respondWith(handleRequest(event.request))
})
async function handleRequest(request) {
// Handle CORS preflight requests
if (request.method === 'OPTIONS') {
return new Response(null, {
headers: {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type, Authorization, CF-Account-ID',
}
})
}
try {
const url = new URL(request.url)
const cfAccountId = request.headers.get('CF-Account-ID')
const authToken = request.headers.get('Authorization')
// Base Cloudflare API URL
const baseApiUrl = `https://api.cloudflare.com/client/v4/accounts/${cfAccountId}/d1`
let response
if (url.pathname === '/databases') {
// List databases
response = await fetch(`${baseApiUrl}/database`, {
headers: {
'Authorization': authToken,
'Content-Type': 'application/json'
}
})
} else if (url.pathname === '/query') {
// Handle database queries
const { dbId, sql } = await request.json()
response = await fetch(`${baseApiUrl}/database/${dbId}/query`, {
method: 'POST',
headers: {
'Authorization': authToken,
'Content-Type': 'application/json'
},
body: JSON.stringify({ sql })
})
} else {
return new Response('Not Found', { status: 404 })
}
const data = await response.json()
// Return response with CORS headers
return new Response(JSON.stringify(data), {
headers: {
'Access-Control-Allow-Origin': '*',
'Content-Type': 'application/json'
}
})
} catch (error) {
return new Response(JSON.stringify({ error: error.message }), {
status: 500,
headers: {
'Access-Control-Allow-Origin': '*',
'Content-Type': 'application/json'
}
})
}
}
- Deploy and copy worker URL
In Cloudflare Pages > Settings > Environment variables:
NEXT_PUBLIC_ACCOUNT_ID=your_cloudflare_account_id
NEXT_PUBLIC_API_TOKEN=your_cloudflare_api_token
NEXT_PUBLIC_CORS_PROXY_URL=your_worker_url
Your D1 dashboard will be live at:
https://your-project.pages.dev
- Initially started as a simple JavaScript project for easy copy-paste deployment
- Zero dependency approach didn't work smoothly and became too complex
- Switched to TypeScript/Nextjs to make things actually work
- Current code is concentrated in
page.tsx
(will be refactored in future updates) - Planning to split components and improve code organization
- GitHub: @malithonline
- LinkedIn: @malithonline
Made with β€οΈ by malith