Every starter kit I've bought died in the same place: the login screen. Not because the auth was broken — because I couldn't find a single valid credential to try it with. Buried in the README, step 9, between the queue worker and the mail config. I gave up and closed the tab.
So when I built my own kit, I made one rule: the login page ships the demo credentials in the open.
Here's the relevant part of my Login.jsx:
{import.meta.env.VITE_DEMO_MODE === 'true' && (
<p className="mt-3 rounded-lg bg-indigo-50 px-4 py-2 text-xs text-indigo-700">
Interactive preview — sign in with the demo credentials below. Data is simulated.
</p>
)}
{/* ... the form ... */}
<div className="mt-6 rounded-lg bg-slate-50 px-4 py-3 text-xs text-slate-600">
<p className="font-semibold text-slate-700">Demo credentials</p>
<p className="mt-1">
Email: <span className="font-mono">admin@demo.io</span>
</p>
<p>
Password: <span className="font-mono">password</span>
</p>
</div>
Two pieces. The box under the form is always there: email admin@demo.io, password password. The banner above the form only renders when the build sets VITE_DEMO_MODE=true, because it makes a claim that's only true in the public preview — "data is simulated", since the demo build runs against an in-memory mock axios client instead of Laravel.
The credentials box isn't gated, because in a real local run those credentials are real. My DatabaseSeeder creates them with firstOrCreate, idempotent, so it works whether you seeded once or five times:
User::firstOrCreate(
['email' => 'admin@demo.io'],
['name' => 'Admin', 'password' => 'password', 'role' => 'admin']
);
Is printing credentials on a login page a security smell? In a production app, yes. In a starter kit, it's documentation that can't be skipped. Nobody reads README step 4; everybody stares at the login page. The credentials box is the fastest path from git clone to seeing the dashboard.
Two smaller details I kept: the submit button disables and switches to "Signing in…" while the request is in flight (no double submits), and a failed login renders a rose-coloured box above the form with the API's message — deliberately generic, never saying which half was wrong.
If you're building a kit: make the login page teach the login. The README is for the 10% who read it.
This login page is from my Laravel + React SaaS Starter Kit — the whole auth loop (Sanctum tokens, roles, seeded demo admin) ships in it: https://kamranofficial.gumroad.com/l/mhekoig
Top comments (0)