Authentication for Lighthouse Scans
Need to scan pages behind a login? Unlighthouse supports every common auth pattern. Find yours below.
Quick Reference
| Auth Type | Best For | Config Key |
|---|---|---|
| Basic Auth | Staging environments with HTTP basic auth | auth |
| Cookies | Session tokens, JWTs in cookies | cookies |
| Headers | Bearer tokens, API keys | extraHeaders |
| localStorage | SPAs storing tokens in localStorage | localStorage |
| Programmatic | Complex login flows, 2FA | hooks.authenticate |
Basic Auth
For sites using HTTP Basic Authentication (the browser popup):
export default defineUnlighthouseConfig({
auth: {
username: process.env.AUTH_USER,
password: process.env.AUTH_PASS,
},
})
Or via CLI:
unlighthouse --site staging.example.com --auth admin:secretpass
Cookies
Most common for session-based auth. Grab your session cookie from browser DevTools (Application → Cookies):
export default defineUnlighthouseConfig({
cookies: [
{
name: 'session_id',
value: 'abc123...',
domain: 'example.com', // Must match your site
path: '/',
},
],
})
Getting the cookie value:
- Log into your site in Chrome
- Open DevTools → Application → Cookies
- Copy the session cookie value
- Paste into config (or use environment variable)
CLI shorthand:
unlighthouse --site example.com --cookies "session_id=abc123"
# Multiple cookies
unlighthouse --site example.com --cookies "session_id=abc123;csrf_token=xyz789"
Headers (Bearer Tokens, API Keys)
For APIs or sites expecting Authorization headers:
export default defineUnlighthouseConfig({
extraHeaders: {
Authorization: `Bearer ${process.env.API_TOKEN}`,
},
})
CLI:
unlighthouse --site api.example.com --extra-headers "Authorization:Bearer abc123"
Query Params
Some staging environments use URL tokens:
export default defineUnlighthouseConfig({
defaultQueryParams: {
access_token: process.env.STAGING_TOKEN,
},
})
Every scanned URL will include ?access_token=...
localStorage (SPAs)
For React/Vue/Angular apps storing auth tokens in localStorage:
export default defineUnlighthouseConfig({
localStorage: {
auth_token: process.env.AUTH_TOKEN,
user_id: '12345',
},
})
Unlighthouse sets these before each page loads.
Programmatic Login (Complex Flows)
For login forms, OAuth flows, or anything the simpler methods can't handle:
export default defineUnlighthouseConfig({
hooks: {
async authenticate({ page }) {
// Navigate to login
await page.goto('https://example.com/login')
// Fill form
await page.type('input[name="email"]', 'test@example.com')
await page.type('input[name="password"]', process.env.PASSWORD)
// Submit and wait for redirect
await Promise.all([
page.click('button[type="submit"]'),
page.waitForNavigation(),
])
},
},
})
This runs once before scanning starts. The session persists for all pages.
Auth Not Sticking?
If authentication isn't persisting between page scans:
export default defineUnlighthouseConfig({
puppeteerOptions: {
userDataDir: './.unlighthouse-session', // Persist browser data
},
lighthouseOptions: {
disableStorageReset: true, // Don't clear storage between pages
skipAboutBlank: true,
},
})
Debugging Auth Issues
Can't tell if auth is working? Watch it happen:
export default defineUnlighthouseConfig({
debug: true,
puppeteerOptions: {
headless: false, // See the browser
slowMo: 100, // Slow it down
},
puppeteerClusterOptions: {
maxConcurrency: 1, // One at a time
},
})
Now you can watch the browser and see exactly where auth fails.
See the Debugging Guide for more techniques.