Files
365devnet/DESIGN_REVIEW.md
Richard Bergsma a767dbb115 Enhance security and localization features across the application
- Added rehype-sanitize plugin to the markdown configuration for improved security against XSS attacks.
- Updated environment variables in the codebase to include new configurations for SMTP and monitoring.
- Implemented secure headers in server and Nginx configurations to bolster security.
- Refactored email handling to prevent spoofing by ensuring safe sender addresses.
- Improved localization by updating language persistence and button components for better user experience.
- Enhanced the uptime API and contact form with better error handling and logging practices.
- Updated dependencies in package.json and package-lock.json for better performance and security.
2025-10-19 21:13:15 +02:00

2.3 KiB

Quick wins (top 5)

  1. Add rehype-sanitize (already applied) and remove unnecessary set:html usages to prevent XSS and improve content robustness.
  2. Eliminate CDN for Mermaid; use local dependency (already applied) to improve performance, privacy, and CSP compliance.
  3. Optimize hero and large images using src/components/common/Image.astro everywhere; enforce width/height and lazy loading for non-LCP images.
  4. Reduce JS on static pages by avoiding unnecessary client-side logs and inline scripts; prefer islands.
  5. Improve form UX: ensure visible error messages, labels, and aria-live regions are consistent; keep focus management for spam/manual-review flows.

Issues table

ID Page/Component Problem Impact Fix
D1 Hero/Hero2/HeroText set:html in multiple slots Med Potential rendering inconsistencies and sanitization risk
D2 Image.astro usage Not consistently used across pages High LCP/CLS and bandwidth
D3 Footer.astro email obfuscation used innerHTML Low Minor XSS risk
D4 Typography Some lines exceed 85ch Low Readability
D5 Forms Inline scripts manage state Med Maintainability/perf

Before/After snippets

Replace set:html for simple line breaks:

<!-- Before -->
<div set:html={text.replace(/\n/g, '<br/>')}></div>

<!-- After -->
<div>
  {text.split('\n').map((line) => (<>
    {line}<br/>
  </>))}
  </div>

Avoid innerHTML when setting modal titles:

// Before
titleEl.innerHTML = title;

// After
titleEl.textContent = String(title);

Asset and typography guidance

  • Use src/components/common/Image.astro for all images. Ensure: alt always set, loading="lazy" for non-LCP, explicit width/height to prevent CLS.
  • Fonts: prefer font-display: swap (already via Inter variable). Limit weights/axes for performance.
  • Containers: keep readable line length using max-w-prose or max-w-[75ch] for long text sections.
  • Hydration: ensure islands only where needed (forms, uptime widgets). Keep content pages server-rendered.