Skip to content

Conversation

@cj-vana
Copy link
Collaborator

@cj-vana cj-vana commented Oct 10, 2025

PR Type

Enhancement, Bug fix


Description

• Comprehensive SEO optimization across all pages with metadata, structured data, and social media tags
• Added reusable SEO utilities including canonical URLs, breadcrumb schemas, and FAQ structured data
• Implemented automated sitemap generation integrated into build process
• Added organization and software application schemas for better search visibility
• Fixed sticky header scrolling calculations and improved visual indicators in show mode pages
• Enhanced Netlify configuration with performance monitoring and security headers


Diagram Walkthrough

flowchart LR
  A["SEO Utilities"] --> B["Page Components"]
  A --> C["Structured Data"]
  D["Build Process"] --> E["Sitemap Generation"]
  F["Show Mode Pages"] --> G["UI Fixes"]
  B --> H["Enhanced Metadata"]
  C --> I["Search Visibility"]
Loading

File Walkthrough

Relevant files
Enhancement
17 files
faq-schemas.ts
Add FAQ schema utilities and content                                         

apps/web/src/schemas/faq-schemas.ts

• Creates FAQ schema utilities for generating structured data

Defines pre-defined FAQ content for resource pages (pinouts, decibel
chart, frequency bands, glossary, microphone techniques)
• Implements
generateFAQSchema function for Schema.org FAQPage structured data

+175/-0 
seo-helpers.ts
Add comprehensive SEO helper utilities                                     

apps/web/src/utils/seo-helpers.ts

• Creates SEO helper functions for generating consistent metadata

Defines generatePageSEO function with Open Graph and Twitter Card
support
• Provides pre-configured SEO settings for all major page
types (dashboard, resources, tools)

+203/-0 
software-schemas.ts
Add software application structured data schemas                 

apps/web/src/schemas/software-schemas.ts

• Creates structured data schemas for software applications
• Defines
schemas for AcoustIQ Lite, AcoustIQ Pro, and SoundDocs platform

Implements Schema.org SoftwareApplication format for better search
visibility

+116/-0 
breadcrumb-schema.ts
Add breadcrumb structured data utilities                                 

apps/web/src/utils/breadcrumb-schema.ts

• Creates breadcrumb schema utility for structured data
• Implements
generateBreadcrumbSchema function for Schema.org BreadcrumbList

Provides helper functions for common breadcrumb patterns (resources,
categories, analyzer)

+87/-0   
canonical-url.ts
Add canonical URL generation utilities                                     

apps/web/src/utils/canonical-url.ts

• Creates canonical URL utility functions
• Implements getCanonicalUrl
and getCanonicalUrlForPath functions
• Removes query parameters and
hash fragments for clean canonical URLs

+31/-0   
organization-schema.ts
Add organization structured data schema                                   

apps/web/src/schemas/organization-schema.ts

• Creates organization structured data schema for SoundDocs
• Defines
Schema.org Organization format with company information
• Includes
GitHub as primary social proof channel

+20/-0   
generate-sitemap.js
Add automated sitemap generation script                                   

apps/web/scripts/generate-sitemap.js

• Creates automated sitemap generation script
• Defines all public
pages with priority and change frequency settings
• Generates XML
sitemap for search engine indexing

+97/-0   
AudioPage.tsx
Add SEO metadata to Audio page                                                     

apps/web/src/pages/AudioPage.tsx

• Adds comprehensive SEO metadata using Helmet
• Implements canonical
URL generation
• Adds Open Graph and Twitter Card meta tags for social
sharing

+625/-574
VideoPage.tsx
Add SEO metadata to Video page                                                     

apps/web/src/pages/VideoPage.tsx

• Adds comprehensive SEO metadata using Helmet
• Implements canonical
URL generation
• Adds Open Graph and Twitter Card meta tags for social
sharing

+194/-156
AnalyzerProPage.tsx
Add SEO metadata and structured data to Analyzer Pro page

apps/web/src/pages/AnalyzerProPage.tsx

• Adds comprehensive SEO metadata with structured data
• Implements
breadcrumb schema and software application schema
• Adds canonical URL
and social media meta tags

+166/-115
SEOHelmet.tsx
Add reusable SEO Helmet component                                               

apps/web/src/components/SEOHelmet.tsx

• Creates reusable SEO Helmet component
• Generates standard meta tags
from configuration object
• Supports Open Graph, Twitter Cards, and
canonical URLs

+44/-0   
ProductionPage.tsx
Add SEO metadata to Production page                                           

apps/web/src/pages/ProductionPage.tsx

• Added comprehensive SEO metadata using Helmet component with title,
description, keywords, and social media tags
• Imported
getCanonicalUrl utility for canonical URL generation
• Wrapped entire
component in React Fragment with Helmet at the top
• Added Open Graph
and Twitter Card meta tags for social media sharing

+449/-400
RatesPage.tsx
Add SEO metadata to Rates page                                                     

apps/web/src/pages/RatesPage.tsx

• Added SEO metadata using Helmet component with comprehensive meta
tags
• Imported generatePageSEO and pageSEO utilities for standardized
SEO configuration
• Added Open Graph and Twitter Card meta tags for
social media optimization
• Wrapped component in React Fragment to
include SEO metadata

+110/-88
AnalyzerPage.tsx
Add SEO metadata and breadcrumb schema to Analyzer page   

apps/web/src/pages/AnalyzerPage.tsx

• Added comprehensive SEO metadata with Helmet component including
title, description, and keywords
• Imported breadcrumb schema
utilities and added structured data for breadcrumbs
• Added canonical
URL and social media meta tags (Open Graph and Twitter Card)
• Wrapped
component in React Fragment for proper SEO structure

+105/-59
AnalyzerLitePage.tsx
Add SEO metadata and structured data to AnalyzerLite page

apps/web/src/pages/AnalyzerLitePage.tsx

• Added SEO metadata using Helmet with specific title, description,
and keywords for AcoustIQ Lite
• Imported breadcrumb schema utilities
and acoustiqLiteSchema for structured data
• Added canonical URL, Open
Graph, and Twitter Card meta tags
• Included JSON-LD structured data
for breadcrumbs and software schema

+76/-28 
LightingPage.tsx
Add SEO metadata to Lighting page                                               

apps/web/src/pages/LightingPage.tsx

• Added SEO metadata using Helmet component with lighting-specific
title, description, and keywords
• Added canonical URL generation and
social media meta tags
• Wrapped component in React Fragment to
include SEO structure

+59/-20 
Landing.tsx
Add SEO metadata and organization schema to Landing page 

apps/web/src/pages/Landing.tsx

• Added comprehensive SEO metadata with canonical URL and social media
tags
• Imported getCanonicalUrl utility and organizationSchema for
structured data
• Updated meta description and keywords for better SEO
optimization
• Added JSON-LD structured data for organization
information

+36/-2   
Configuration changes
3 files
robots.txt
Optimize robots.txt for SEO                                                           

apps/web/public/robots.txt

• Updates robots.txt with SEO optimization
• Disallows protected
routes to save crawl budget
• Adds crawl delay and sitemap reference

+30/-0   
netlify.toml
Add Netlify performance and security configuration             

netlify.toml

• Added Lighthouse plugin for performance monitoring and SEO auditing

• Configured security headers (X-Content-Type-Options,
X-Frame-Options, X-XSS-Protection, Referrer-Policy)
• Added cache
control headers for static assets with long-term caching
• Increased
Node.js memory allocation for large builds

+40/-2   
package.json
Add sitemap generation to build process                                   

apps/web/package.json

• Modified build script to generate sitemap before building (node
scripts/generate-sitemap.js && vite build)
• Added new
generate:sitemap script for standalone sitemap generation

+2/-1     
Bug fix
2 files
SharedShowModePage.tsx
Fix sticky header scrolling and improve visual indicators

apps/web/src/pages/SharedShowModePage.tsx

• Fixed scrolling calculation to account for both table header and
section headers with proper sticky height calculation
• Changed next
cue indicator color from red to orange (bg-red-500 to bg-orange-500)

Improved z-index calculation for sticky headers to prevent text
bleed-through

+22/-8   
ShowModePage.tsx
Fix sticky header scrolling and update cue indicators       

apps/web/src/pages/ShowModePage.tsx

• Fixed scrolling calculation to properly account for sticky headers
with combined height calculation
• Changed next cue indicator color
from red to orange for better visual distinction
• Improved z-index
calculation for section headers to prevent text overlap issues

+22/-8   

cj-vana and others added 2 commits October 9, 2025 15:27
Enhanced the Show Mode and shared view link pages with better visual
indicators and fixed auto-scroll behavior for live performance use.

Visual improvements:
- Changed next cue indicator from red to orange for better distinction
- Current cue remains green, next cue now orange (more intuitive)
- Updated legend indicators to match new color scheme

Auto-scroll fixes:
- Fixed auto-scroll positioning to account for sticky header heights
- Items now scroll to visible position below all sticky elements
- Added proper offset calculation (89px total: 49px table + 40px section)
- Added 20px padding offset for better visibility

Sticky header layering fixes:
- Fixed multi-line section headers showing through next headers
- Implemented progressive z-index values (z-11, z-12, z-13...)
- Each subsequent header now properly appears on top of previous ones
- Prevents text bleed-through when headers wrap to multiple lines

Changes:
- ShowModePage.tsx: Orange next cue, fixed auto-scroll, z-index layering
- SharedShowModePage.tsx: Same fixes applied for consistency

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Add complete SEO infrastructure with meta tags, structured data, and
automated sitemap generation to improve search engine visibility.

SEO Infrastructure:
- Add automated sitemap generation script (23 URLs with priorities)
- Create reusable SEO utilities (canonical URLs, breadcrumbs, helpers)
- Add SEOHelmet component for consistent meta tag implementation
- Integrate sitemap generation into build process

Structured Data (Schema.org):
- Add Organization schema with GitHub social proof
- Add SoftwareApplication schemas for AcoustIQ Lite & Pro
- Add BreadcrumbList schemas for navigation hierarchy
- Add FAQ schemas (25 questions across 5 categories)
- Remove placeholder rating data to prevent guideline violations

Meta Tags & SEO:
- Add complete meta tags to 10 major pages:
  - Landing, Audio, Video, Lighting, Production pages
  - Analyzer hub, Lite, and Pro pages
  - Resources and Rates pages
- Optimize Landing page description (234→151 chars)
- Add canonical URLs to prevent duplicate content
- Add Open Graph and Twitter Card tags for social sharing
- Add comprehensive keyword targeting

Performance & Technical SEO:
- Add Netlify performance headers (caching, security)
- Add Netlify Lighthouse CI plugin for monitoring
- Optimize robots.txt with 20+ disallow rules for auth-gated content
- Normalize sitemap URLs with trailing slashes
- Remove inaccurate lastmod tags from sitemap

Files Created:
- apps/web/scripts/generate-sitemap.js
- apps/web/src/components/SEOHelmet.tsx
- apps/web/src/utils/canonical-url.ts
- apps/web/src/utils/breadcrumb-schema.ts
- apps/web/src/utils/seo-helpers.ts
- apps/web/src/schemas/organization-schema.ts
- apps/web/src/schemas/software-schemas.ts
- apps/web/src/schemas/faq-schemas.ts

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@netlify
Copy link

netlify bot commented Oct 10, 2025

Deploy Preview for sounddocsbeta ready!

Name Link
🔨 Latest commit 8c4088f
🔍 Latest deploy log https://app.netlify.com/projects/sounddocsbeta/deploys/68e92e078967570009414ff9
😎 Deploy Preview https://deploy-preview-110--sounddocsbeta.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@qodo-code-review
Copy link
Contributor

CI Feedback 🧐

A test triggered by this PR failed. Here is an AI-generated analysis of the failure:

Action: typescript-checks

Failed stage: ESLint on changed files [❌]

Failure summary:

The action failed because ESLint reported errors in changed files (with --max-warnings 0), causing
the lint job to exit with code 1. Specific errors:
- apps/web/src/pages/AnalyzerProPage.tsx:24:31 —
useMemo is defined but never used (@typescript-eslint/no-unused-vars)
-
apps/web/src/pages/LightingPage.tsx:6:10 — Lightbulb is defined but never used
(@typescript-eslint/no-unused-vars)
- apps/web/src/pages/SharedShowModePage.tsx:79:21 — Unexpected
any. Specify a different type (@typescript-eslint/no-explicit-any)
-
apps/web/src/pages/ShowModePage.tsx:
- 29:20 — Unexpected any. Specify a different type
(@typescript-eslint/no-explicit-any)
- 71:40 — Unexpected any. Specify a different type
(@typescript-eslint/no-explicit-any)
- 137:80 — Unexpected any. Specify a different type
(@typescript-eslint/no-explicit-any)
- 159:21 — Unexpected any. Specify a different type
(@typescript-eslint/no-explicit-any)
ESLint summary: 9 problems (7 errors, 2 warnings). The workflow
is configured to fail on any errors.

Relevant error logs:
1:  ##[group]Runner Image Provisioner
2:  Hosted Compute Agent
...

174:  + prettier 3.5.3
175:  + typescript 5.9.2
176:  + typescript-eslint 8.39.1
177:  . prepare$ husky
178:  . prepare: Done
179:  Done in 4.4s using pnpm v9.15.9
180:  ##[group]Run # Convert comma-separated list to space-separated for ESLint
181:  �[36;1m# Convert comma-separated list to space-separated for ESLint�[0m
182:  �[36;1mFILES="apps/web/src/schemas/faq-schemas.ts,apps/web/src/schemas/organization-schema.ts,apps/web/src/schemas/software-schemas.ts,apps/web/src/utils/breadcrumb-schema.ts,apps/web/src/utils/canonical-url.ts,apps/web/src/utils/seo-helpers.ts,apps/web/src/components/SEOHelmet.tsx,apps/web/scripts/generate-sitemap.js,apps/web/src/pages/AnalyzerLitePage.tsx,apps/web/src/pages/AnalyzerPage.tsx,apps/web/src/pages/AnalyzerProPage.tsx,apps/web/src/pages/AudioPage.tsx,apps/web/src/pages/Landing.tsx,apps/web/src/pages/LightingPage.tsx,apps/web/src/pages/ProductionPage.tsx,apps/web/src/pages/RatesPage.tsx,apps/web/src/pages/SharedShowModePage.tsx,apps/web/src/pages/ShowModePage.tsx,apps/web/src/pages/VideoPage.tsx"�[0m
183:  �[36;1mFILES_ARRAY=$(echo "$FILES" | tr ',' ' ')�[0m
184:  �[36;1m�[0m
185:  �[36;1mecho "Running ESLint on changed files:"�[0m
186:  �[36;1mecho "$FILES_ARRAY" | tr ' ' '\n'�[0m
187:  �[36;1m�[0m
188:  �[36;1m# Run ESLint only on changed files�[0m
189:  �[36;1m# Note: ESLint might need context from imported files, but will only report errors in specified files�[0m
190:  �[36;1mnpx eslint $FILES_ARRAY --max-warnings 0 || EXIT_CODE=$?�[0m
191:  �[36;1m�[0m
192:  �[36;1m# If ESLint found issues, fail the check�[0m
193:  �[36;1mif [ "${EXIT_CODE:-0}" -ne 0 ]; then�[0m
...

209:  apps/web/src/utils/seo-helpers.ts
210:  apps/web/src/components/SEOHelmet.tsx
211:  apps/web/scripts/generate-sitemap.js
212:  apps/web/src/pages/AnalyzerLitePage.tsx
213:  apps/web/src/pages/AnalyzerPage.tsx
214:  apps/web/src/pages/AnalyzerProPage.tsx
215:  apps/web/src/pages/AudioPage.tsx
216:  apps/web/src/pages/Landing.tsx
217:  apps/web/src/pages/LightingPage.tsx
218:  apps/web/src/pages/ProductionPage.tsx
219:  apps/web/src/pages/RatesPage.tsx
220:  apps/web/src/pages/SharedShowModePage.tsx
221:  apps/web/src/pages/ShowModePage.tsx
222:  apps/web/src/pages/VideoPage.tsx
223:  /home/runner/work/sounddocs/sounddocs/apps/web/src/pages/AnalyzerProPage.tsx
224:  ##[error]   24:31  error    'useMemo' is defined but never used                                                                                   @typescript-eslint/no-unused-vars
225:  ##[warning]  172:6   warning  React Hook useEffect has a missing dependency: 'fetchMeasurements'. Either include it or remove the dependency array  react-hooks/exhaustive-deps
226:  /home/runner/work/sounddocs/sounddocs/apps/web/src/pages/LightingPage.tsx
227:  ##[error]  6:10  error  'Lightbulb' is defined but never used  @typescript-eslint/no-unused-vars
228:  /home/runner/work/sounddocs/sounddocs/apps/web/src/pages/SharedShowModePage.tsx
229:  ##[error]  79:21  error  Unexpected any. Specify a different type  @typescript-eslint/no-explicit-any
230:  /home/runner/work/sounddocs/sounddocs/apps/web/src/pages/ShowModePage.tsx
231:  ##[error]   29:20  error    Unexpected any. Specify a different type                                                                        @typescript-eslint/no-explicit-any
232:  ##[error]   71:40  error    Unexpected any. Specify a different type                                                                        @typescript-eslint/no-explicit-any
233:  ##[error]  137:80  error    Unexpected any. Specify a different type                                                                        @typescript-eslint/no-explicit-any
234:  ##[error]  159:21  error    Unexpected any. Specify a different type                                                                        @typescript-eslint/no-explicit-any
235:  ##[warning]  209:6   warning  React Hook useEffect has a missing dependency: 'itemTimerId'. Either include it or remove the dependency array  react-hooks/exhaustive-deps
236:  ✖ 9 problems (7 errors, 2 warnings)
237:  ❌ ESLint found issues in changed files
238:  ##[error]Process completed with exit code 1.
239:  Post job cleanup.

@qodo-code-review
Copy link
Contributor

qodo-code-review bot commented Oct 10, 2025

PR Compliance Guide 🔍

Below is a summary of compliance checks for this PR:

Security Compliance
🔴
Undefined variable

Description: The script references BUILD_DATE in a console log without defining it, which can cause a
runtime ReferenceError during build execution and potentially break sitemap generation.
generate-sitemap.js [86-91]

Referred Code
  console.log("✅ Sitemap generated successfully!");
  console.log(`📄 ${pages.length} URLs included`);
  console.log(`📍 Location: ${sitemapPath}`);
  console.log(`🗓️  Last modified: ${BUILD_DATE}`);
} catch (error) {
  console.error("❌ Error generating sitemap:", error);
SSR unsafe window access

Description: Direct use of window without environment checks can throw errors during server-side
rendering or prerendering contexts, breaking page loads and SEO rendering.
canonical-url.ts [13-18]

Referred Code
export const getCanonicalUrl = (): string => {
  // Get the pathname without query params or hash
  const path = window.location.pathname;

  // Combine base URL with path
  return `${BASE_URL}${path}`;
External OG image host

Description: Open Graph and Twitter image URLs use a third-party host (postimg.cc); if compromised,
content spoofing or mixed content issues could occur—use controlled domain assets for
social previews.
AudioPage.tsx [1473-1505]

Referred Code
<Helmet>
  <title>Audio Documentation Tools | Patch Sheets & Mic Plots | SoundDocs</title>
  <meta
    name="description"
    content="Professional audio documentation tools for live events. Create patch sheets, mic plots, input lists, and stage plots. Free forever for audio engineers and FOH technicians."
  />
  <meta
    name="keywords"
    content="audio documentation, patch sheet, mic plot, input list, stage plot, audio engineer tools, FOH, monitor engineer, wireless mic management"
  />

  {/* Canonical URL */}
  <link rel="canonical" href={getCanonicalUrl()} />

  {/* Open Graph - Social Media */}
  <meta property="og:type" content="website" />
  <meta property="og:url" content="https://sounddocs.org/audio" />
  <meta property="og:title" content="Audio Documentation Tools | SoundDocs" />
  <meta
    property="og:description"
    content="Professional audio documentation tools for live events. Create patch sheets, mic plots, and input lists. Free forever."


 ... (clipped 12 lines)
External OG image host

Description: Open Graph and Twitter image URLs rely on an external image host which may be unreliable
or pose integrity risks; prefer first-party CDN or domain for preview images.
VideoPage.tsx [144-176]

Referred Code
<Helmet>
  <title>LED Pixel Mapping & Video Tools | SoundDocs</title>
  <meta
    name="description"
    content="Professional LED pixel mapping and video documentation tools. Create LED wall designs, standard pixel maps, and video signal flow documentation. Free forever for video technicians."
  />
  <meta
    name="keywords"
    content="LED pixel mapping, video mapping, LED wall designer, pixel map software, video documentation, video signal flow, video technician tools"
  />

  {/* Canonical URL */}
  <link rel="canonical" href={getCanonicalUrl()} />

  {/* Open Graph - Social Media */}
  <meta property="og:type" content="website" />
  <meta property="og:url" content="https://sounddocs.org/video" />
  <meta property="og:title" content="LED Pixel Mapping & Video Tools | SoundDocs" />
  <meta
    property="og:description"
    content="Professional LED pixel mapping and video documentation tools. Create LED wall designs and pixel maps. Free forever."


 ... (clipped 12 lines)
Ticket Compliance
🎫 No ticket provided
  • Create ticket/issue
Codebase Duplication Compliance
Codebase context is not defined

Follow the guide to enable codebase context checks.

Custom Compliance
No custom compliance provided

Follow the guide to enable custom compliance check.

  • Update
Compliance status legend 🟢 - Fully Compliant
🟡 - Partial Compliant
🔴 - Not Compliant
⚪ - Requires Further Human Verification
🏷️ - Compliance label

@qodo-code-review
Copy link
Contributor

qodo-code-review bot commented Oct 10, 2025

PR Code Suggestions ✨

Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
Possible issue
Prevent server-side rendering crash

Add a check for the existence of the window object in getCanonicalUrl to prevent
crashes during server-side rendering. Return a safe default if window is not
available.

apps/web/src/utils/canonical-url.ts [13-19]

 export const getCanonicalUrl = (): string => {
+  if (typeof window === "undefined") {
+    return ""; // Or handle as appropriate for your SSR setup
+  }
   // Get the pathname without query params or hash
   const path = window.location.pathname;
 
   // Combine base URL with path
   return `${BASE_URL}${path}`;
 };
  • Apply / Chat
Suggestion importance[1-10]: 9

__

Why: This suggestion correctly identifies a critical bug that would cause a ReferenceError and crash the application during server-side rendering, making it a high-priority fix.

High
Fix script crash from undefined variable

Define the BUILD_DATE variable before it is used in the console.log statement to
prevent a ReferenceError that crashes the sitemap generation script.

apps/web/scripts/generate-sitemap.js [89]

+const BUILD_DATE = new Date().toISOString();
 console.log(`🗓️  Last modified: ${BUILD_DATE}`);
  • Apply / Chat
Suggestion importance[1-10]: 9

__

Why: The suggestion correctly identifies a ReferenceError that would crash the sitemap generation script. Fixing this is critical for the script to function as intended.

High
Prevent incorrect canonical URL generation
Suggestion Impact:The canonicalUrl generation was modified so that when window is undefined (SSR), it now falls back to undefined instead of the base URL.

code diff:

-export const generatePageSEO = (seo: PageSEO) => {
-  const baseUrl = "https://sounddocs.org";
-  const canonicalUrl = seo.canonicalPath
-    ? `${baseUrl}${seo.canonicalPath}`
-    : typeof window !== "undefined"
-      ? `${baseUrl}${window.location.pathname}`
-      : baseUrl;

Modify the canonicalUrl generation to fall back to undefined instead of the base
URL during server-side rendering. This prevents incorrect canonical tags when
the path is unknown on the server.

apps/web/src/utils/seo-helpers.ts [22-26]

 const canonicalUrl = seo.canonicalPath
   ? `${baseUrl}${seo.canonicalPath}`
   : typeof window !== "undefined"
     ? `${baseUrl}${window.location.pathname}`
-    : baseUrl;
+    : undefined;

[Suggestion processed]

Suggestion importance[1-10]: 8

__

Why: This is a valid and important correction that prevents a significant SEO issue where pages rendered server-side could have incorrect canonical URLs, potentially leading to duplicate content problems.

Medium
High-level
Decouple SEO content from code

Move hardcoded SEO content, such as FAQs and meta descriptions, from TypeScript
files into external data files (e.g., JSON) or a headless CMS. This change will
improve maintainability and allow non-developers to update content without code
changes.

Examples:

apps/web/src/utils/seo-helpers.ts [51-203]
export const pageSEO = {
  dashboard: {
    title: "Dashboard | SoundDocs",
    description:
      "Your SoundDocs dashboard. Access all your patch sheets, stage plots, run of shows, pixel maps, and production schedules in one place.",
    keywords: "dashboard, my documents, audio documentation, production documents",
    canonicalPath: "/dashboard",
  },

  allPatchSheets: {

 ... (clipped 143 lines)
apps/web/src/schemas/faq-schemas.ts [35-175]
export const resourceFAQs = {
  commonPinouts: [
    {
      question: "What is the difference between XLR and TRS cables?",
      answer:
        "XLR cables use a 3-pin connector and are primarily used for balanced microphone and line-level signals in professional audio. TRS (Tip-Ring-Sleeve) cables can carry balanced or stereo signals and are commonly found on headphones and some professional equipment. XLR connectors lock in place, while TRS connectors do not.",
    },
    {
      question: "Which pin is hot on an XLR connector?",
      answer:

 ... (clipped 131 lines)

Solution Walkthrough:

Before:

// apps/web/src/utils/seo-helpers.ts

export const pageSEO = {
  dashboard: {
    title: "Dashboard | SoundDocs",
    description:
      "Your SoundDocs dashboard. Access all your patch sheets...",
    keywords: "dashboard, my documents, audio documentation...",
    canonicalPath: "/dashboard",
  },
  allPatchSheets: {
    title: "My Patch Sheets | SoundDocs",
    description:
      "View and manage all your audio patch sheets...",
    ...
  },
  // ... many more hardcoded page SEO objects
};

After:

// content/seo-content.json
{
  "pageSEO": {
    "dashboard": {
      "title": "Dashboard | SoundDocs",
      "description": "Your SoundDocs dashboard. Access all your patch sheets...",
      "keywords": "dashboard, my documents, audio documentation...",
      "canonicalPath": "/dashboard"
    },
    "allPatchSheets": {
      "title": "My Patch Sheets | SoundDocs",
      "description": "View and manage all your audio patch sheets...",
      "..."
    }
  }
}

// apps/web/src/utils/seo-helpers.ts
import seoContent from 'content/seo-content.json';

export const pageSEO = seoContent.pageSEO;
Suggestion importance[1-10]: 8

__

Why: The suggestion correctly identifies that a large amount of SEO content is hardcoded, which is a valid architectural concern impacting maintainability and scalability, and proposes a standard best practice to decouple content from code.

Medium
Security
Remove deprecated security header
Suggestion Impact:The commit removed the X-XSS-Protection = "1; mode=block" header from the Netlify headers configuration.

code diff:

-# Security and performance headers
-[[headers]]
-  for = "/*"
-  [headers.values]
-    X-Content-Type-Options = "nosniff"
-    X-Frame-Options = "DENY"
-    X-XSS-Protection = "1; mode=block"
-    Referrer-Policy = "strict-origin-when-cross-origin"
-

Remove the deprecated X-XSS-Protection security header from the configuration,
as it is no longer supported by modern browsers and can introduce security
risks.

netlify.toml [27-34]

 # Security and performance headers
 [[headers]]
   for = "/*"
   [headers.values]
     X-Content-Type-Options = "nosniff"
     X-Frame-Options = "DENY"
-    X-XSS-Protection = "1; mode=block"
     Referrer-Policy = "strict-origin-when-cross-origin"
+    # X-XSS-Protection should be removed. A Content-Security-Policy header should be added here instead.

[Suggestion processed]

Suggestion importance[1-10]: 8

__

Why: This is a valid and important security suggestion, as the X-XSS-Protection header is deprecated and can create vulnerabilities in modern browsers. Removing it is a recommended best practice.

Medium
General
Dynamically set the Open Graph URL

Replace the hardcoded og:url meta tag with a dynamic call to getCanonicalUrl()
to ensure it always matches the canonical URL of the page.

apps/web/src/pages/ProductionPage.tsx [1409-1418]

 {/* Canonical URL */}
 <link rel="canonical" href={getCanonicalUrl()} />
 
 {/* Open Graph - Social Media */}
 <meta property="og:type" content="website" />
-<meta property="og:url" content="https://sounddocs.org/production" />
+<meta property="og:url" content={getCanonicalUrl()} />
 <meta
   property="og:title"
   content="Production Schedule & Run of Show Software | SoundDocs"
 />
  • Apply / Chat
Suggestion importance[1-10]: 6

__

Why: The suggestion correctly identifies that the hardcoded og:url should be dynamic using getCanonicalUrl() for better maintainability and SEO consistency, which is a good practice.

Low
Optimize z-index calculation in loop

Optimize the z-index calculation for sticky headers by using an external counter
before the loop, reducing the operation from O(N*M) to O(N) for better
performance.

apps/web/src/pages/SharedShowModePage.tsx [326-335]

+// This counter should be declared before the .map() loop
+let headerIndexCounter = 0;
+
+// Inside the .map((item, index) => { ... })
 if (item.type === "header") {
-  // Calculate z-index based on header position to prevent text bleed-through
-  // Each subsequent header should have a higher z-index than the previous
-  const headerIndex = items
-    .slice(0, index + 1)
-    .filter((i) => i.type === "header").length;
-  const zIndex = 10 + headerIndex;
+  // Increment counter for each header to calculate a unique z-index
+  headerIndexCounter++;
+  const zIndex = 10 + headerIndexCounter;
   rowClass = "bg-gray-700 hover:bg-gray-600 font-semibold sticky top-[40px]";
   rowStyle.zIndex = zIndex;
 } else {
  • Apply / Chat
Suggestion importance[1-10]: 5

__

Why: The suggestion correctly identifies an inefficient zIndex calculation within a loop and proposes a more performant O(N) solution, which improves code quality and performance for large lists.

Low
  • Update

@cj-vana cj-vana merged commit 1e82424 into beta Oct 10, 2025
7 of 9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant