diff --git a/app/sites/[id]/pagespeed/page.tsx b/app/sites/[id]/pagespeed/page.tsx
index c66ef4f..2a5c39b 100644
--- a/app/sites/[id]/pagespeed/page.tsx
+++ b/app/sites/[id]/pagespeed/page.tsx
@@ -526,9 +526,7 @@ export default function PageSpeedPage() {
{groupAudits.length > 0 && (
-
- {groupAudits.map(audit =>
)}
-
+
)}
{groupPassed.length > 0 && (
@@ -550,6 +548,52 @@ export default function PageSpeedPage() {
)
}
+// * Group audits by sub-group within a category (e.g., "Names and Labels", "Contrast")
+function AuditsBySubGroup({ audits }: { audits: AuditSummary[] }) {
+ // * Collect unique sub-groups in order of appearance
+ const subGroupOrder: string[] = []
+ const bySubGroup: Record = {}
+
+ for (const audit of audits) {
+ const key = audit.sub_group || '__none__'
+ if (!bySubGroup[key]) {
+ bySubGroup[key] = []
+ subGroupOrder.push(key)
+ }
+ bySubGroup[key].push(audit)
+ }
+
+ // * If no sub-groups exist, render flat list
+ if (subGroupOrder.length === 1 && subGroupOrder[0] === '__none__') {
+ return (
+
+ {audits.map(audit =>
)}
+
+ )
+ }
+
+ return (
+
+ {subGroupOrder.map(key => {
+ const items = bySubGroup[key]
+ const title = items[0]?.sub_group_title
+ return (
+
+ {title && (
+
+ {title}
+
+ )}
+
+ {items.map(audit =>
)}
+
+
+ )
+ })}
+
+ )
+}
+
// * Severity indicator based on audit score (pagespeed.web.dev style)
function AuditSeverityIcon({ score }: { score: number | null }) {
if (score === null) {
diff --git a/lib/api/pagespeed.ts b/lib/api/pagespeed.ts
index b036d52..840b3df 100644
--- a/lib/api/pagespeed.ts
+++ b/lib/api/pagespeed.ts
@@ -21,6 +21,8 @@ export interface AuditSummary {
savings_ms?: number
category: 'opportunity' | 'diagnostic' | 'passed'
group?: string // "performance", "accessibility", "best-practices", "seo"
+ sub_group?: string // "a11y-names-labels", "a11y-contrast", etc.
+ sub_group_title?: string // "Names and Labels", "Contrast", etc.
details?: AuditDetailItem[]
}