-
+
{isDe
? 'Kostenlose Erstberatung für Ihr Vorhaben.'
: 'Free initial consultation for your project.'}
diff --git a/components/blog/TableOfContents.tsx b/components/blog/TableOfContents.tsx
index e7e1c406..567a0d76 100644
--- a/components/blog/TableOfContents.tsx
+++ b/components/blog/TableOfContents.tsx
@@ -53,7 +53,7 @@ export default function TableOfContents({ headings, locale }: TableOfContentsPro
return (
diff --git a/package.json b/package.json
index 879ccb6c..f9311595 100644
--- a/package.json
+++ b/package.json
@@ -97,7 +97,7 @@
"test:og": "vitest run tests/og-image.test.ts",
"check:og": "tsx scripts/check-og-images.ts",
"check:mdx": "node scripts/validate-mdx.mjs",
- "check:a11y": "start-server-and-test start http://localhost:3000 'pa11y-ci'",
+ "check:a11y": "pa11y-ci",
"check:wcag": "tsx ./scripts/wcag-sitemap.ts",
"cms:branding:local": "DIRECTUS_URL=${DIRECTUS_URL:-http://cms.klz.localhost} npx tsx --env-file=.env scripts/setup-directus-branding.ts",
"cms:branding:testing": "DIRECTUS_URL=https://cms.testing.klz-cables.com npx tsx --env-file=.env scripts/setup-directus-branding.ts",
diff --git a/scripts/pagespeed-sitemap.ts b/scripts/pagespeed-sitemap.ts
index 29c08922..16a07a58 100644
--- a/scripts/pagespeed-sitemap.ts
+++ b/scripts/pagespeed-sitemap.ts
@@ -12,8 +12,7 @@ import * as path from 'path';
* 3. Runs Lighthouse CI on those URLs
*/
-const targetUrl =
- process.argv[2] || process.env.NEXT_PUBLIC_BASE_URL || 'https://testing.klz-cables.com';
+const targetUrl = process.argv[2] || process.env.NEXT_PUBLIC_BASE_URL || 'http://localhost:3000';
const limit = process.env.PAGESPEED_LIMIT ? parseInt(process.env.PAGESPEED_LIMIT) : 20; // Default limit to avoid infinite runs
const gatekeeperPassword = process.env.GATEKEEPER_PASSWORD || 'klz2026';
diff --git a/scripts/wcag-sitemap.ts b/scripts/wcag-sitemap.ts
index 3e6cedb0..f9278fe0 100644
--- a/scripts/wcag-sitemap.ts
+++ b/scripts/wcag-sitemap.ts
@@ -12,8 +12,7 @@ import * as path from 'path';
* 3. Runs pa11y-ci on those URLs
*/
-const targetUrl =
- process.argv[2] || process.env.NEXT_PUBLIC_BASE_URL || 'https://testing.klz-cables.com';
+const targetUrl = process.argv[2] || process.env.NEXT_PUBLIC_BASE_URL || 'http://localhost:3000';
const limit = process.env.PAGESPEED_LIMIT ? parseInt(process.env.PAGESPEED_LIMIT) : 20;
const gatekeeperPassword = process.env.GATEKEEPER_PASSWORD || 'klz2026';
@@ -80,22 +79,38 @@ async function main() {
...baseConfig,
defaults: {
...baseConfig.defaults,
- actions: [
- `set cookie klz_gatekeeper_session=${gatekeeperPassword} domain=${domain} path=/`,
- ...(baseConfig.defaults?.actions || []),
- ],
+ threshold: 0, // Force threshold to 0 so all errors are shown in JSON
+ runners: ['axe'],
+ ignore: [...(baseConfig.defaults?.ignore || []), 'color-contrast'],
+ chromeLaunchConfig: {
+ ...baseConfig.defaults?.chromeLaunchConfig,
+ args: [
+ ...(baseConfig.defaults?.chromeLaunchConfig?.args || []),
+ '--no-sandbox',
+ '--disable-setuid-sandbox',
+ ],
+ },
+ headers: {
+ Cookie: `klz_gatekeeper_session=${gatekeeperPassword}`,
+ },
timeout: 60000, // Increase timeout for slower pages
},
urls: urls,
};
- const tempConfigPath = path.join(process.cwd(), '.pa11yci.temp.json');
- const reportPath = path.join(process.cwd(), '.pa11yci-report.json');
+ // Create output directory
+ const outputDir = path.join(process.cwd(), '.pa11yci');
+ if (!fs.existsSync(outputDir)) {
+ fs.mkdirSync(outputDir, { recursive: true });
+ }
+
+ const tempConfigPath = path.join(outputDir, 'config.temp.json');
+ const reportPath = path.join(outputDir, 'report.json');
fs.writeFileSync(tempConfigPath, JSON.stringify(tempConfig, null, 2));
// 3. Execute pa11y-ci
console.log(`\n💻 Executing pa11y-ci...`);
- const pa11yCommand = `npx pa11y-ci --config .pa11yci.temp.json --reporter json > .pa11yci-report.json`;
+ const pa11yCommand = `npx pa11y-ci --config .pa11yci/config.temp.json --reporter json > .pa11yci/report.json`;
try {
execSync(pa11yCommand, {
@@ -113,9 +128,18 @@ async function main() {
const summaryTable = Object.keys(reportData.results).map((url) => {
const results = reportData.results[url];
- const errors = results.filter((r: any) => r.type === 'error').length;
- const warnings = results.filter((r: any) => r.type === 'warning').length;
- const notices = results.filter((r: any) => r.type === 'notice').length;
+ // Results might have errors or just a top level message if it crashed
+ let errors = 0;
+ let warnings = 0;
+ let notices = 0;
+
+ if (Array.isArray(results)) {
+ // pa11y action execution errors come as objects with a message but no type
+ const actionErrors = results.filter((r: any) => !r.type && r.message).length;
+ errors = results.filter((r: any) => r.type === 'error').length + actionErrors;
+ warnings = results.filter((r: any) => r.type === 'warning').length;
+ notices = results.filter((r: any) => r.type === 'notice').length;
+ }
// Clean URL for display
const displayUrl = url.replace(targetUrl, '') || '/';
@@ -138,6 +162,7 @@ async function main() {
console.log(`\n📈 Result: ${cleanPages}/${totalPages} pages are error-free.`);
if (totalErrors > 0) {
console.log(` Total Errors discovered: ${totalErrors}`);
+ process.exitCode = 1;
}
}
@@ -152,11 +177,9 @@ async function main() {
}
process.exit(1);
} finally {
- // Clean up temp files
- ['.pa11yci.temp.json', '.pa11yci-report.json'].forEach((f) => {
- const p = path.join(process.cwd(), f);
- if (fs.existsSync(p)) fs.unlinkSync(p);
- });
+ // Clean up temp config file, keep report
+ const tempConfigPath = path.join(process.cwd(), '.pa11yci/config.temp.json');
+ if (fs.existsSync(tempConfigPath)) fs.unlinkSync(tempConfigPath);
}
}