From f00256bb9738043a79fad6a071ea90ce83635022 Mon Sep 17 00:00:00 2001 From: jjenk Date: Wed, 15 Jul 2026 13:50:19 +0200 Subject: [PATCH] refactor: add aria-hidden to SVGs on Faq page. This closes issue #193 --- functions/_csp.generated.js | 2 +- public/sitemap.xml | 12 +- src/components/Faq.astro | 331 ++++++++++++++++++++++-------------- 3 files changed, 215 insertions(+), 130 deletions(-) diff --git a/functions/_csp.generated.js b/functions/_csp.generated.js index 187e2ac..e21cc54 100644 --- a/functions/_csp.generated.js +++ b/functions/_csp.generated.js @@ -1,4 +1,4 @@ // AUTO-GENERATED by scripts/generate-cf-headers.mjs (postbuild). Do not edit. // The hash CSP (~3.1KB) exceeds Cloudflare Pages _headers 2000-char/line cap, // so it is emitted from functions/_middleware.js instead. -export const CSP = "default-src 'self'; script-src 'self' https://cloud.umami.is https://analytics.cloudcertprep.io https://challenges.cloudflare.com https://static.cloudflareinsights.com 'sha256-1Uy5rMOY/hZdQ2MhftlrmWXyV2Ce1sdcQb7GVV6GvF8=' 'sha256-4wS1F2VSs+KocMEzSX6o31sihZlUsFY4O//mU2D/p5M=' 'sha256-7b+r90WqKBD/k76rwesVkVvXm//Xtgz8HIu37ibV3QM=' 'sha256-BF0290pkb3jxQsE7z00xR8Imp8X34FLC88L0lkMnrGw=' 'sha256-CkZuL49QNykSSTa76nqJWUkexEXu0cIbxnDFEKB4gRE=' 'sha256-E0VVNoQlDMTduwBOQX2FLdAZ2Jj4PpTRIXMNFwBSYq8=' 'sha256-G6KtXpsooc/Wl8IiRORzxmQ5v04JyRyhxa69f+igaZA=' 'sha256-SaCkFfPruIdTXT8/97JArQmGxiJAL2o4bBDvSgJ5y3Q=' 'sha256-d2ntn0ds3/Zo1c7nO9XDb/p9ZL3Q0OxLCIY/pyvHw04=' 'sha256-eIXWvAmxkr251LJZkjniEK5LcPF3NkapbJepohwYRIc=' 'sha256-j1S2Mq44MtvWYphzkkfMRQ8i5nKpXUrqTDAx3tqoAZs=' 'sha256-jySfNAkYE8dsxJsd0fpLdcF7xJ02FoC0K1n+AFn3jdA=' 'sha256-kUyObzOZwVBCaBmyX1Hh3avOAJNU0tR9OhftxlA1tOw=' 'sha256-s1a6MsVSCBYY+xacPMleqN3GHgUaHOLtSiYlOKM/coE=' 'sha256-tOKj5BdoCjpajI8qXeGS4A2XbSDQFcJ2T216662yBv8=' 'sha256-zB6xj12k8tjB66OpGLFSOlMzIBFrIDPIdq2M4dQu4BY='; style-src 'self' 'unsafe-hashes' 'sha256-+N4rhDMrQOzZ5/gukFLPo314KbSrcf7Cj7yWjFwiA4c=' 'sha256-3NQ9YQpqUavgWArjqS+RlpnAC+CssQvI+yjbU2hciDg=' 'sha256-3rvSp7DI5v9LkS8wsvqriMSPMdtEvB871yPTOkn3pJw=' 'sha256-4UqlUsRWKTRuwiCAw05XjI6z9H3uDRGE3ndyo/D1eT8=' 'sha256-5WCWQ3TzLARQP4jvG0lPQ/WbzuKFb7ipgSnjb3TsHYM=' 'sha256-6IhMRCz7S4MX63zNDI4id4YlHys+O3VEnckBeQ3CP/E=' 'sha256-6MIyHce/SsapcXGM7rmqXRnSYJ9voWLJdYye+dEgQfc=' 'sha256-7oaTSwBQvhuMEzrHCHGr9ILP265VEyOXYhwYMvZoOPc=' 'sha256-9wt2Kmuno597q6eJRVwIn1G09JUvTm3KwjtY24tcQ/8=' 'sha256-AkGc/9SiOd74zk72UnCdLs+k10sM4iy2uKmgoXkaHe0=' 'sha256-B3PaPcKWfZFm/lkA1qno3yxKgzZfP98STce1GXQ8ZXY=' 'sha256-BIBCjsKScD5ETxK7/wgbTpCFBjb+ps1jyMHwM15wDtQ=' 'sha256-GopttSTYqQnCagn5eIh0V9OjLoM38u8B7DE9/vc4/VA=' 'sha256-Gv0yzjygz2QwFg5T2Ar6SgqzxScuxTVRe48ynZ/L+dk=' 'sha256-H7ORESDF+95GLgYFo7zPfCKqS133TadC0SOC6CydYvM=' 'sha256-HAwfCxgk/+SZeuf9ZAFs7TRKReIYTObZftH5MXu68hw=' 'sha256-JenfgrfwDYXkTpGOf2ECiJs2kqoPwlkgPT3xROk5Nes=' 'sha256-LLhVAOrgIiYeb8EF9zoOCggBIgJCziS6smOU/UG9Lh8=' 'sha256-LPspWMaai4zES+TnHs0xUMy2keAiV14nnVrTB3kkTNs=' 'sha256-NUZDIu/dNGaicg48DcR/t6stCpDYmHqwp5+iQAWWQ40=' 'sha256-Q02k/6PEr5DImWATrr9+cPv+JM/KaJ7duIUvLPV27sk=' 'sha256-SxhYhm9ubDlLl04eeqYaQYHN8Cq34MZa1oWb1g6Qxys=' 'sha256-WkIrthYCmUYH131h/UfbqszUeL7BNUUssuGdovfTO3w=' 'sha256-YdJ0bP84NUafbOgZno9tjrrqGXJD+enAIVcnS1h+1HA=' 'sha256-Z6hPztPx9qWe2XfTK5wxl+pnONeROrFhtdU8kW/wExA=' 'sha256-mtGVlSmZvSdGPDOCfeadALN0m+6wSLomjKNt7ckTu8I=' 'sha256-n2RoYT/tYrzFJZXFcGZkuGe2kabAwh3tXaGialstLds=' 'sha256-oEnEbuBXhR53RaMWuE91zLUqW2DeHFdNd3uk1hTxIxg=' 'sha256-oVsU82+RuO7YBCXmpQNTUwazthj5VrPG1ZStsFeDR2M=' 'sha256-pXrl6eVgDFq0tYS/oE8Zj5cBgw2SNVij8DwibdlH0Mo=' 'sha256-qVNPyPmBi7hcryM/Do8AbrO9Fj9+pT8QU8m0CilHn5k=' 'sha256-uzy+Ox7eBFRpllkuL2UtV0C1p4YZlXe8RG6eg+SYLco=' 'sha256-vv9IoKo7BSLbWcUHr3tNmfNVmm5L/9Cfn2H6LMk7/ow=' 'sha256-xIVdJ053nY+hMy8nmZMQs4EvHEMIJEN0gJZivD/SXb8=' 'sha256-yacTBydsbGOm2fH2Sy1MAVwSdCH5X3+zMEYfhoLiRgE='; img-src 'self' data:; font-src 'self' data:; connect-src 'self' https://gegbjeluttwwiccyukka.supabase.co wss://gegbjeluttwwiccyukka.supabase.co https://cloud.umami.is https://analytics.cloudcertprep.io https://gateway.umami.is https://challenges.cloudflare.com https://cloudflareinsights.com; frame-src https://challenges.cloudflare.com; object-src 'none'; frame-ancestors 'none'; base-uri 'self'; form-action 'self'; upgrade-insecure-requests" +export const CSP = "default-src 'self'; script-src 'self' https://cloud.umami.is https://analytics.cloudcertprep.io https://challenges.cloudflare.com https://static.cloudflareinsights.com 'sha256-1Uy5rMOY/hZdQ2MhftlrmWXyV2Ce1sdcQb7GVV6GvF8=' 'sha256-4wS1F2VSs+KocMEzSX6o31sihZlUsFY4O//mU2D/p5M=' 'sha256-7b+r90WqKBD/k76rwesVkVvXm//Xtgz8HIu37ibV3QM=' 'sha256-BF0290pkb3jxQsE7z00xR8Imp8X34FLC88L0lkMnrGw=' 'sha256-CkZuL49QNykSSTa76nqJWUkexEXu0cIbxnDFEKB4gRE=' 'sha256-E0VVNoQlDMTduwBOQX2FLdAZ2Jj4PpTRIXMNFwBSYq8=' 'sha256-G6KtXpsooc/Wl8IiRORzxmQ5v04JyRyhxa69f+igaZA=' 'sha256-SaCkFfPruIdTXT8/97JArQmGxiJAL2o4bBDvSgJ5y3Q=' 'sha256-d2ntn0ds3/Zo1c7nO9XDb/p9ZL3Q0OxLCIY/pyvHw04=' 'sha256-eIXWvAmxkr251LJZkjniEK5LcPF3NkapbJepohwYRIc=' 'sha256-j1S2Mq44MtvWYphzkkfMRQ8i5nKpXUrqTDAx3tqoAZs=' 'sha256-jySfNAkYE8dsxJsd0fpLdcF7xJ02FoC0K1n+AFn3jdA=' 'sha256-kUyObzOZwVBCaBmyX1Hh3avOAJNU0tR9OhftxlA1tOw=' 'sha256-s1a6MsVSCBYY+xacPMleqN3GHgUaHOLtSiYlOKM/coE=' 'sha256-tOKj5BdoCjpajI8qXeGS4A2XbSDQFcJ2T216662yBv8=' 'sha256-zB6xj12k8tjB66OpGLFSOlMzIBFrIDPIdq2M4dQu4BY='; style-src 'self' 'unsafe-hashes' 'sha256-+N4rhDMrQOzZ5/gukFLPo314KbSrcf7Cj7yWjFwiA4c=' 'sha256-3NQ9YQpqUavgWArjqS+RlpnAC+CssQvI+yjbU2hciDg=' 'sha256-3rvSp7DI5v9LkS8wsvqriMSPMdtEvB871yPTOkn3pJw=' 'sha256-4UqlUsRWKTRuwiCAw05XjI6z9H3uDRGE3ndyo/D1eT8=' 'sha256-5WCWQ3TzLARQP4jvG0lPQ/WbzuKFb7ipgSnjb3TsHYM=' 'sha256-6IhMRCz7S4MX63zNDI4id4YlHys+O3VEnckBeQ3CP/E=' 'sha256-6MIyHce/SsapcXGM7rmqXRnSYJ9voWLJdYye+dEgQfc=' 'sha256-7oaTSwBQvhuMEzrHCHGr9ILP265VEyOXYhwYMvZoOPc=' 'sha256-9wt2Kmuno597q6eJRVwIn1G09JUvTm3KwjtY24tcQ/8=' 'sha256-AkGc/9SiOd74zk72UnCdLs+k10sM4iy2uKmgoXkaHe0=' 'sha256-B3PaPcKWfZFm/lkA1qno3yxKgzZfP98STce1GXQ8ZXY=' 'sha256-BIBCjsKScD5ETxK7/wgbTpCFBjb+ps1jyMHwM15wDtQ=' 'sha256-GopttSTYqQnCagn5eIh0V9OjLoM38u8B7DE9/vc4/VA=' 'sha256-Gv0yzjygz2QwFg5T2Ar6SgqzxScuxTVRe48ynZ/L+dk=' 'sha256-H7ORESDF+95GLgYFo7zPfCKqS133TadC0SOC6CydYvM=' 'sha256-HAwfCxgk/+SZeuf9ZAFs7TRKReIYTObZftH5MXu68hw=' 'sha256-JenfgrfwDYXkTpGOf2ECiJs2kqoPwlkgPT3xROk5Nes=' 'sha256-LLhVAOrgIiYeb8EF9zoOCggBIgJCziS6smOU/UG9Lh8=' 'sha256-LPspWMaai4zES+TnHs0xUMy2keAiV14nnVrTB3kkTNs=' 'sha256-NUZDIu/dNGaicg48DcR/t6stCpDYmHqwp5+iQAWWQ40=' 'sha256-Q02k/6PEr5DImWATrr9+cPv+JM/KaJ7duIUvLPV27sk=' 'sha256-SxhYhm9ubDlLl04eeqYaQYHN8Cq34MZa1oWb1g6Qxys=' 'sha256-WkIrthYCmUYH131h/UfbqszUeL7BNUUssuGdovfTO3w=' 'sha256-YdJ0bP84NUafbOgZno9tjrrqGXJD+enAIVcnS1h+1HA=' 'sha256-Z6hPztPx9qWe2XfTK5wxl+pnONeROrFhtdU8kW/wExA=' 'sha256-mtGVlSmZvSdGPDOCfeadALN0m+6wSLomjKNt7ckTu8I=' 'sha256-n2RoYT/tYrzFJZXFcGZkuGe2kabAwh3tXaGialstLds=' 'sha256-oEnEbuBXhR53RaMWuE91zLUqW2DeHFdNd3uk1hTxIxg=' 'sha256-oVsU82+RuO7YBCXmpQNTUwazthj5VrPG1ZStsFeDR2M=' 'sha256-pXrl6eVgDFq0tYS/oE8Zj5cBgw2SNVij8DwibdlH0Mo=' 'sha256-qVNPyPmBi7hcryM/Do8AbrO9Fj9+pT8QU8m0CilHn5k=' 'sha256-uzy+Ox7eBFRpllkuL2UtV0C1p4YZlXe8RG6eg+SYLco=' 'sha256-vv9IoKo7BSLbWcUHr3tNmfNVmm5L/9Cfn2H6LMk7/ow=' 'sha256-xIVdJ053nY+hMy8nmZMQs4EvHEMIJEN0gJZivD/SXb8=' 'sha256-yacTBydsbGOm2fH2Sy1MAVwSdCH5X3+zMEYfhoLiRgE='; img-src 'self' data:; font-src 'self' data:; connect-src 'self' https://your-project.supabase.co wss://your-project.supabase.co https://cloud.umami.is https://analytics.cloudcertprep.io https://gateway.umami.is https://challenges.cloudflare.com https://cloudflareinsights.com; frame-src https://challenges.cloudflare.com; object-src 'none'; frame-ancestors 'none'; base-uri 'self'; form-action 'self'; upgrade-insecure-requests" diff --git a/public/sitemap.xml b/public/sitemap.xml index 702c914..563108b 100644 --- a/public/sitemap.xml +++ b/public/sitemap.xml @@ -32,7 +32,7 @@ https://www.cloudcertprep.io/aws/clf-c02 - 2026-07-04 + 2026-07-05 weekly 0.9 @@ -50,7 +50,7 @@ https://www.cloudcertprep.io/aws/clf-c02/cloud-concepts - 2026-07-04 + 2026-07-05 weekly 0.7 @@ -59,7 +59,7 @@ https://www.cloudcertprep.io/aws/clf-c02/security-and-compliance - 2026-07-04 + 2026-07-05 weekly 0.7 @@ -68,7 +68,7 @@ https://www.cloudcertprep.io/aws/clf-c02/cloud-technology-and-services - 2026-07-04 + 2026-07-05 weekly 0.7 @@ -77,7 +77,7 @@ https://www.cloudcertprep.io/aws/clf-c02/billing-pricing-and-support - 2026-07-04 + 2026-07-05 weekly 0.7 @@ -131,7 +131,7 @@ https://www.cloudcertprep.io/blog - 2026-07-05 + 2026-07-15 weekly 0.7 diff --git a/src/components/Faq.astro b/src/components/Faq.astro index 0f8ccc1..24a1749 100644 --- a/src/components/Faq.astro +++ b/src/components/Faq.astro @@ -16,149 +16,234 @@ * * Satisfies: R6.20, R6.10 (FAQPage JSON-LD parity). */ -import { FAQ_ENTRIES, FAQ_CATEGORY_LABEL, FAQ_CATEGORY_ORDER } from '../lib/seo-data' -import { serializeJsonLd } from '../lib/jsonld' -import { splitLinks } from '../lib/faqLinks' +import { + FAQ_ENTRIES, + FAQ_CATEGORY_LABEL, + FAQ_CATEGORY_ORDER, +} from "../lib/seo-data"; +import { serializeJsonLd } from "../lib/jsonld"; +import { splitLinks } from "../lib/faqLinks"; interface SimpleEntry { - question: string - answer: string + question: string; + answer: string; } interface Props { - certCode?: string - genericOnly?: boolean - /** Custom entries override the registry. Flat (no category grouping). */ - entries?: SimpleEntry[] - /** Heading id used by aria-labelledby (defaults to "faq-heading"). */ - headingId?: string - /** Visible heading text (defaults to "Frequently asked questions"). */ - headingLabel?: string - /** Heading type scale, to match the host page's other section H2s. Default is - * the large editorial scale used by home + cert hubs; denser pages (domain - * landings, whose section H2s are text-xl/2xl) pass the smaller scale. */ - headingClass?: string + certCode?: string; + genericOnly?: boolean; + /** Custom entries override the registry. Flat (no category grouping). */ + entries?: SimpleEntry[]; + /** Heading id used by aria-labelledby (defaults to "faq-heading"). */ + headingId?: string; + /** Visible heading text (defaults to "Frequently asked questions"). */ + headingLabel?: string; + /** Heading type scale, to match the host page's other section H2s. Default is + * the large editorial scale used by home + cert hubs; denser pages (domain + * landings, whose section H2s are text-xl/2xl) pass the smaller scale. */ + headingClass?: string; } const { - certCode, - genericOnly, - entries: customEntries, - headingId = 'faq-heading', - headingLabel = 'Frequently asked questions', - headingClass = 'font-display text-[1.75rem] md:text-[2.25rem] font-semibold tracking-[-0.02em]', -} = Astro.props + certCode, + genericOnly, + entries: customEntries, + headingId = "faq-heading", + headingLabel = "Frequently asked questions", + headingClass = "font-display text-[1.75rem] md:text-[2.25rem] font-semibold tracking-[-0.02em]", +} = Astro.props; -const useCustom = !!customEntries +const useCustom = !!customEntries; const registryEntries = useCustom - ? [] - : genericOnly - ? FAQ_ENTRIES.filter(e => !e.certCode) - : certCode - ? FAQ_ENTRIES.filter(e => !e.certCode || e.certCode === certCode) - : FAQ_ENTRIES + ? [] + : genericOnly + ? FAQ_ENTRIES.filter((e) => !e.certCode) + : certCode + ? FAQ_ENTRIES.filter((e) => !e.certCode || e.certCode === certCode) + : FAQ_ENTRIES; const grouped = useCustom - ? [] - : FAQ_CATEGORY_ORDER.map(category => ({ - category, - entries: registryEntries.filter(e => e.category === category), - })).filter(g => g.entries.length > 0) + ? [] + : FAQ_CATEGORY_ORDER.map((category) => ({ + category, + entries: registryEntries.filter((e) => e.category === category), + })).filter((g) => g.entries.length > 0); const faqJsonLd = serializeJsonLd({ - '@context': 'https://schema.org', - '@type': 'FAQPage', - mainEntity: (useCustom ? customEntries! : registryEntries).map(entry => ({ - '@type': 'Question', - name: entry.question, - acceptedAnswer: { '@type': 'Answer', text: entry.answer }, - })), -}) + "@context": "https://schema.org", + "@type": "FAQPage", + mainEntity: (useCustom ? customEntries! : registryEntries).map((entry) => ({ + "@type": "Question", + name: entry.question, + acceptedAnswer: { "@type": "Answer", text: entry.answer }, + })), +}); -const chevron = '' +const chevron = ''; ---
-