Build an internal dashboard with Lovable using this step by step guide covering setup, data integration, widgets, access controls and team metrics

Book a call with an Expert
Starting a new venture? Need to upgrade your web app? RapidDev builds application with your growth in mind.
A simple internal dashboard: create a protected React page at src/pages/Dashboard.tsx, add a small server route at src/pages/api/internal-stats.ts that reads a Lovable Cloud Secret (INTERNAL_API_KEY or SUPABASE_URL/KEY) and returns stats, wire a secure link in src/App.tsx, and configure the Secrets in Lovable Cloud. Do everything via Lovable Chat edits + Preview + Publish (no terminal). Use Supabase only if you add its URL/KEY to Lovable Secrets and call it from the server route; never put private keys in client code.
We will add an internal-only dashboard page and a server API route that returns simple metrics. The route is protected by an API key stored in Lovable Cloud Secrets. The Dashboard fetches that server route and renders data. No terminal required — all changes happen via Lovable Chat Mode file edits, Preview, and Publish.
Use Chat Mode to edit/create files (UI edits or file diffs), add secrets in Lovable Cloud Secrets UI, test with Preview (the built-in simulator), then Publish. If you need DB migrations or external builds, export to GitHub from Lovable and perform those steps outside Lovable (labelled explicitly).
Prompt 1 — Create server API route (protected)
Goal: Add a server-side API at src/pages/api/internal-stats.ts that validates an API key from request header and returns JSON stats (uptime, dummy userCount). Create or update these files:
Acceptance criteria: Done when a GET to /api/internal-stats with header x-internal-key equals the SECRET returns { uptime, userCount } and unauthorized otherwise.
Secrets needed: Lovable Cloud Secret named INTERNAL_API_KEY (set via Lovable Secrets UI).
File content guidance (for you to paste into Lovable chat edit):
// create src/pages/api/internal-stats.ts
import type { NextApiRequest, NextApiResponse } from 'next'
// read from process.env.INTERNAL_API_KEY (Lovable Secrets)
export default function handler(req: NextApiRequest, res: NextApiResponse) {
const key = req.headers['x-internal-key'] as string | undefined
if (!key || key !== process.env.INTERNAL_API_KEY) {
return res.status(401).json({ error: 'unauthorized' })
}
// simple demo stats
const uptime = process.uptime()
const userCount = 42 // replace with real DB call in a later step
return res.status(200).json({ uptime, userCount })
}
Prompt 2 — Create Dashboard page that calls the protected API
Goal: Add a React page at src/pages/dashboard.tsx that fetches /api/internal-stats using the internal key from a client-side fetch header (do NOT hardcode; read via an API route proxy or use a short-lived token — for this example, use Lovable Preview only: the page will call the server API and supply header from a safe fetch using a server-side helper). Files:
Acceptance criteria: Done when visiting /dashboard in Preview shows uptime and userCount fetched from /api/internal-stats.
File content guidance:
// create src/pages/dashboard.tsx
import React, { useEffect, useState } from 'react'
export default function Dashboard() {
const [data, setData] = useState<{ uptime?: number; userCount?: number } | null>(null)
const [error, setError] = useState<string | null>(null)
useEffect(() => {
async function load() {
try {
const res = await fetch('/api/internal-stats', { headers: { 'x-internal-key': '' } }) // Lovable will inject secret on server; leave blank in client
if (!res.ok) throw new Error(await res.text())
setData(await res.json())
} catch (e: any) {
setError(e.message)
}
}
load()
}, [])
if (error) return <div>error: {error}</div>
if (!data) return <div>loading…</div>
return (
<div>
<h1>Internal Dashboard</h1>
<p>Uptime: {data.uptime}</p>
<p>User count: {data.userCount}</p>
</div>
)
}
Prompt 3 — Add server-side proxy helper (securely inject secret on server)
Goal: Make client requests not carry the secret. Create src/pages/api/dashboard-proxy.ts which calls internal-stats with the secret read server-side and returns the result to the client. Files:
Acceptance criteria: Done when /api/dashboard-proxy returns same JSON as /api/internal-stats but the client never sends the secret header.
File content guidance:
// create src/pages/api/dashboard-proxy.ts
import type { NextApiRequest, NextApiResponse } from 'next'
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
const key = process.env.INTERNAL_API_KEY
if (!key) return res.status(500).json({ error: 'missing secret' })
// call internal-stats endpoint within same deployment
const baseUrl = `${req.headers['x-forwarded-proto'] || 'https'}://${req.headers.host}`
const r = await fetch(`${baseUrl}/api/internal-stats`, { headers: { 'x-internal-key': key } })
const json = await r.json()
return res.status(r.status).json(json)
}
This plan uses Lovable-native features: Chat Mode file edits, Preview, Publish, and Lovable Cloud Secrets. It avoids invented UI/terminal features. If you need DB migrations or background workers, export to GitHub and run those steps outside Lovable (I can include that workflow if you want it next).
This prompt helps an AI assistant understand your setup and guide to build the feature
This prompt helps an AI assistant understand your setup and guide to build the feature
This prompt helps an AI assistant understand your setup and guide to build the feature

Book a call with an Expert
Starting a new venture? Need to upgrade your web app? RapidDev builds application with your growth in mind.
The short answer: build the dashboard so AI code generation is a controlled, auditable pipeline — use template-driven generation, strict permissioning, sandboxed previews (never auto-run produced code), store every generation in a database for auditing, use Lovable’s Secrets UI for API keys, use Chat Mode edits + file diffs + Preview to iterate, and push changes to GitHub (and CI) for validation before publishing to production.
Design the system as a pipeline with clear handoffs: user input -> template + prompt -> model call -> preview/diff -> human review -> commit/publish. Treat the model as a helper that proposes changes, not an automated deployer.
Use Lovable Cloud Secrets UI for all API keys (OpenAI, Supabase, GitHub). Never embed secrets in chat logs or saved prompts. Limit keys to least privilege (short-lived tokens, limited scopes).
Remember: Lovable has no terminal. Use its native actions: Chat Mode edits, file diffs/patches, Preview, Publish, Secrets UI, GitHub sync/export for anything that needs CI or migrations.
// serverless function: generates code via OpenAI and records audit to Supabase
import fetch from "node-fetch";
import { createClient } from "@supabase/supabase-js";
// create clients using env variables (set these in Lovable Secrets UI)
const supabase = createClient(process.env.SUPABASE_URL, process.env.SUPABASE_SERVICE_KEY);
// POST body: { userId, templateName, params }
export default async function handler(req, res) {
// validate input
const { userId, templateName, params } = req.body;
if (!userId || !templateName) return res.status(400).json({ error: "missing" });
// build prompt from a template (keep templates server-side)
const prompt = `Generate a React component named ${params.componentName} with prop types...`;
// call OpenAI
const r = await fetch("https://api.openai.com/v1/chat/completions", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${process.env.OPENAI_API_KEY}`,
},
body: JSON.stringify({
model: "gpt-4-0613",
messages: [{ role: "system", content: "You are a code generator." }, { role: "user", content: prompt }],
max_tokens: 1500,
}),
});
const data = await r.json();
const generated = data?.choices?.[0]?.message?.content ?? "";
// store audit + generated code in Supabase
await supabase.from("ai_generations").insert({
user_id: userId,
template: templateName,
params,
generated_code: generated,
meta: data,
created_at: new Date().toISOString(),
});
// return to UI for preview/review
res.json({ generated });
}
Protect production: never auto-deploy generated artifacts. Use GitHub sync from Lovable to create a PR instead of publishing directly, run CI (tests, linters, SAST), and require code review and merge protection.
From startups to enterprises and everything in between, see for yourself our incredible impact.
Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We’ll discuss your project and provide a custom quote at no cost.