Inspiration

The Storyblok Accessibility Auditor was inspired by the frequent gap between developers building accessible components and content teams unintentionally introducing accessibility issues. Editors often miss critical details—such as filling in Alt text for images or leaving placeholder content like "lorem ipsum"—which can degrade SEO and fail compliance checks. I wanted a tool that creates a proactive governance layer right in the content pipeline, ensuring accessibility isn't an afterthought.

What it does

The Auditor is a dynamic, full-stack tool that automatically validates Storyblok content for structural accessibility and quality rules. Users provide a Story Slug and dynamically select which checks to run.

Rule Enforcement: Checks for issues like ensuring only one H1 heading exists, verifying all image components have non-empty Alt text, and scanning for placeholder text.

Actionable Feedback: The report provides instant visual feedback, showing the exact JSON component and field that failed a rule. This dramatically shortens the time needed for content teams to fix errors.

How we built it

I have implemented a decoupled, production-ready architecture:

Frontend (Vue.js / Vercel): The user interface, built with Vue.js 3, manages the Dynamic Rule selection and presents the audit report. It sends the content JSON and an array of active rules to the backend. The frontend is hosted on Vercel.

Backend (Go / Render): The core logic runs on a high-performance Go API using the gin framework. It uses a recursive function to efficiently traverse the deeply nested Storyblok JSON. This API executes the conditional audit logic and returns a structured report including the JSON chunk where the issue was found (ProblemData). The backend is deployed as a service on Render.

Challenges we ran into

Go Version Incompatibility: My initial build failed because the project required Go version ≥1.25.1, but the runner was using Go 1.25.0.

Cloud Port Binding: I struggled with deployment to Render because our Go application was hardcoded to listen on port 8080 locally, causing it to fail when the Render container required binding to a dynamic PORT environment variable (as seen in the deployment logs).

Recursive JSON Traversal: Building a robust Go function to recursively search arbitrary, nested JSON structures (map[string]interface{}) was complex but necessary to cover all possible Storyblok component placements.

Accomplishments that we're proud of

Successful Decoupled Deployment: I have achieved a clean, robust deployment with the Go API on Render and the Vue Frontend on Vercel, showcasing a real-world, scalable architecture.

Dynamic Rule System: I have built a modular backend that allows the frontend to fully control which audit functions run, making the tool easily extensible.

Effective Visual Feedback: Successfully passing the exact problematic JSON chunk from the Go backend to the Vue frontend allows for a superior user experience by providing precise context for every content error.

What we learned

Go Cloud Deployment Best Practices: I have solidified my understanding of the critical need to retrieve and bind to the os.Getenv("PORT") variable when deploying Go applications to containerized cloud environments like Render.

Advanced Go Data Structures: Gained significant experience in designing efficient recursive algorithms in Go to handle unpredictable, deeply nested JSON data structures inherent to headless CMS content.

Full-Stack Cohesion: Learned how to design API payloads (like the Issue struct with ProblemData) specifically to enable complex frontend features, ensuring seamless data flow between the two services.

What's next for Storyblok Accessibility Auditor

Expand Rule Set: Implement more sophisticated rules, such as checking for generic link text (e.g., "click here") or validating color contrast ratios.

Storyblok App Integration: Convert the auditor into a full Storyblok App, allowing content editors to run the audit directly within the CMS interface before publishing.

User Authentication: Implement proper token handling and OAuth for more secure and feature-rich access to private Storyblok spaces.

Built With

Share this project:

Updates