How OpenSEO Handles Lighthouse Audits: Workflow Architecture and Implementation
OpenSEO handles Lighthouse audits by orchestrating them as a configurable phase within the site audit workflow, fetching raw data from the DataForSEO API, extracting only essential issue-level details for cost-efficient storage in Cloudflare R2, and serving curated results through dedicated server-side API functions.
OpenSEO is an open-source SEO automation platform that integrates Google Lighthouse auditing into its comprehensive site analysis pipeline. Unlike storing bulky full reports, the system implements a lightweight, issue-centric approach that prioritizes actionable data while minimizing storage overhead. This article examines the technical implementation details found in the every-app/open-seo repository to explain exactly how the platform processes, stores, and delivers Lighthouse audit results.
Workflow Orchestration: Controlling When Lighthouse Runs
The Lighthouse audit phase is governed by src/server/workflows/siteAuditWorkflowPhases.ts, which implements the audit orchestration layer. This workflow checks the lighthouseStrategy option in the audit request—supporting values "auto" (enabled) or "none" (disabled)—to determine whether to execute the Lighthouse phase.
When the strategy is "auto", the workflow executes selectLighthousePages to generate a representative sample of pages from the site. It then schedules parallel fetch jobs for each selected URL and tracks completion and failure counts across the batch. If the strategy is "none", the system skips the entire Lighthouse phase, conserving API calls and compute resources.
Data Acquisition: Fetching Reports from DataForSEO
Individual fetch jobs invoke the DataForSEO Lighthouse endpoint at /v3/on_page/lighthouse/live/json. This interaction is wrapped by the fetchLighthouseResult function defined in src/server/lib/dataforseo/lighthouse.ts.
The function handles the raw HTTP communication with the third-party API and returns the complete Lighthouse JSON payload. This abstraction isolates the external API dependency and provides a clean interface for the workflow to retrieve audit data without managing low-level network logic.
Payload Processing and Cloud Storage Optimization
To prevent storage bloat, OpenSEO implements aggressive payload reduction through readStoredLighthousePayload in src/server/lib/lighthousePayload.ts. This processing layer extracts only issue-level data and essential metadata (scores and key metrics) while discarding the heavy full Lighthouse report.
The trimmed payload is then persisted to Cloudflare R2 object storage via the utilities in src/server/lib/r2.ts. The audit record stored in the primary database (site.lighthouse) receives an r2Key identifier that points to the actual payload location. This design keeps database records lightweight while maintaining access to detailed results through the object storage layer.
Server-Side API Functions for Data Retrieval
Two primary server functions expose Lighthouse data to the front-end in src/serverFunctions/lighthouse.ts:
getAuditLighthouseIssues– Retrieves a specific audit result byresultId, fetches the payload from R2 usinggetJsonFromR2, and returns a curated object containing final URL, strategy (mobile/desktop), timestamps, scores, metrics, and the structured issues array.exportAuditLighthouseIssues– Generates downloadable export files by callingbuildLighthouseExportFile. This function supports both"category"mode (filtering by specific Lighthouse categories like "performance") and"full"mode (exporting all issues).
Both functions utilize shared validation schemas to ensure data integrity before returning results to the client.
Schema Validation and Type Safety
Data integrity is enforced through Zod schemas defined in src/types/schemas/lighthouse.ts. These schemas validate the shape of incoming requests and outgoing responses, guaranteeing that only required fields for UI display or export processing are accepted.
The schemas also provide default values for the lighthouseStrategy option and define the structure for lighthouseAuditIssueSchema and lighthouseAuditExportSchema, ensuring type safety across the server function layer.
Practical Implementation Examples
Requesting Lighthouse Issues for a Specific Result
To retrieve processed Lighthouse data for display in the UI:
import { getAuditLighthouseIssues } from "@/serverFunctions/lighthouse";
await getAuditLighthouseIssues({
resultId: "abcd‑1234", // Lighthouse result identifier
});
This function re-hydrates the stored payload from R2 and returns an object shaped like:
{
id: string;
finalUrl: string;
strategy: "mobile" | "desktop";
createdAt: Date;
hasIssueDetails: boolean;
scores: Record<string, number> | null;
metrics: Record<string, number> | null;
issues: Array<LighthouseIssue>;
}
Exporting Lighthouse Data for Reporting
To generate downloadable audit reports:
import { exportAuditLighthouseIssues } from "@/serverFunctions/lighthouse";
await exportAuditLighthouseIssues({
resultId: "abcd‑1234",
mode: "category", // or "full"
category: "performance", // required when mode === "category"
});
The function returns a downloadable file (CSV or JSON) generated by buildLighthouseExportFile, making it ideal for sharing audit results with stakeholders or archiving historical performance data.
Configuring Lighthouse Strategy in Audit Requests
When creating a new site audit, control Lighthouse execution via the strategy parameter:
await fetch("/api/audit", {
method: "POST",
body: JSON.stringify({
urls: ["https://example.com"],
lighthouseStrategy: "auto", // "none" disables Lighthouse
// …other audit options
}),
});
Setting lighthouseStrategy to "none" completely bypasses the Lighthouse phase, reducing API usage and processing time for audits where Core Web Vitals analysis is unnecessary.
Summary
OpenSEO implements Lighthouse auditing through a cost-efficient, multi-layered architecture:
- Orchestration in
siteAuditWorkflowPhases.tscontrols execution based on thelighthouseStrategyoption - Data acquisition via
fetchLighthouseResultinterfaces with the DataForSEO API to retrieve raw reports - Storage optimization through
readStoredLighthousePayloadreduces data to issue-level essentials before storing in Cloudflare R2 - API exposure via
getAuditLighthouseIssuesandexportAuditLighthouseIssuesprovides flexible access to audit results - Type safety enforced by Zod schemas in
src/types/schemas/lighthouse.tsensures reliable data handling across the pipeline
Frequently Asked Questions
How does OpenSEO decide which pages to audit with Lighthouse?
The selectLighthousePages function within src/server/workflows/siteAuditWorkflowPhases.ts automatically selects a representative sample of pages from the site when lighthouseStrategy is set to "auto". This sampling approach balances comprehensive coverage with API cost efficiency, focusing on diverse page templates rather than auditing every single URL.
Where does OpenSEO store the actual Lighthouse report data?
Rather than storing full reports in the primary database, OpenSEO persists processed payloads to Cloudflare R2 object storage and stores only the r2Key reference in the audit record (site.lighthouse). This architecture significantly reduces database size and costs while maintaining rapid access to detailed issue data when needed.
Can I disable Lighthouse auditing to save API credits?
Yes. When creating an audit request, set lighthouseStrategy to "none" in the request payload. According to the orchestration logic in siteAuditWorkflowPhases.ts, this value causes the workflow to skip the entire Lighthouse phase, eliminating DataForSEO API calls for Lighthouse data while still performing other SEO analysis tasks.
What data is included in the Lighthouse export files?
The exportAuditLighthouseIssues function generates files containing the curated issue list, scores, and metrics extracted during payload processing. Depending on the mode parameter ("category" or "full"), the export includes either issues filtered to a specific Lighthouse category (such as performance or accessibility) or the complete issue set, formatted as CSV or JSON for stakeholder reporting.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →