fix(seo): improve heading hierarchy and alt text for accessibility#3661
fix(seo): improve heading hierarchy and alt text for accessibility#3661PierreBrisorgueil merged 2 commits intomasterfrom
Conversation
- Change hero h2 tags to h1 for proper page heading hierarchy - Add dynamic headingLevel prop to content component (default h2) - Change steps h5 to h3 and gallery h4 to h3 for correct nesting - Change team member h4 to h3 for consistent heading levels - Add alt prop to img component with fallback chain (alt > title > 'Decorative image') - Use descriptive dynamic alt text on hero banner image - Add alt attributes to gallery carousel items
|
Warning Rate limit exceeded
⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (6)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #3661 +/- ##
=======================================
Coverage 98.55% 98.55%
=======================================
Files 19 19
Lines 485 485
Branches 121 121
=======================================
Hits 478 478
Misses 7 7 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Pull request overview
This PR targets SEO/accessibility in the home module by improving heading hierarchy (avoiding skipped levels) and making image alt text more descriptive.
Changes:
- Updated several headings to better follow an
h1 → h2 → h3structure (hero, steps, gallery, team member). - Added an optional
altprop toHomeImgComponentand improved hero/banner alt text handling. - Added a configurable
headingLevelprop toHomeContentComponentfor dynamic subtitle heading tags.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| src/modules/home/components/utils/home.img.component.vue | Adds alt prop and updates <v-img> alt fallback behavior. |
| src/modules/home/components/utils/home.content.component.vue | Renders subtitle as a dynamic heading tag via new headingLevel prop. |
| src/modules/home/components/team.member.component.vue | Adjusts member name heading level for improved hierarchy. |
| src/modules/home/components/home.steps.component.vue | Updates step title heading level in the timeline opposite slot. |
| src/modules/home/components/home.hero.component.vue | Promotes hero title to h1 and improves banner alt text binding. |
| src/modules/home/components/home.gallery.component.vue | Updates slide subtitle heading level and adds alt-like text to slides. |
Comments suppressed due to low confidence (1)
src/modules/home/components/home.steps.component.vue:52
- With
homeContentComponentnow rendering its subtitle as anh2by default, each timeline card will likely contain anh2after thish3step title, which is a backward jump in the heading hierarchy. Consider passing an explicitheadingLevelto the nestedhomeContentComponent(e.g., one level below this step title) or changing the opposite slot markup to non-heading text so the document outline remains monotonic.
<h3 class="text-headline-small text-md-headline-medium text-secondary font-weight-bold" v-text="item.title"></h3>
</template>
<v-card :class="`${config.vuetify.theme.rounded} my-8 pb-2`" :flat="config.vuetify.theme.flat" :style="cardStyle">
<homeImgComponent v-if="item.img && !item.reversed" :img="item.img"></homeImgComponent>
<homeContentComponent :setup="item" variant="card" alignment="center"></homeContentComponent>
<homeImgComponent v-if="item.img && item.reversed" :img="item.img"></homeImgComponent>
- Use empty string instead of 'Decorative image' for images without alt/title to avoid misleading screen reader announcements - Use static 'Hero banner' alt to avoid markdown syntax leaking into alt text - Change headingLevel default from 2 to 3 to match original component docs and avoid hierarchy conflicts in nested contexts (e.g. steps timeline)
# [1.5.0](v1.4.0...v1.5.0) (2026-04-01) ### Bug Fixes * **analytics:** PostHog api_host bug + identify/group on login ([#3772](#3772)) ([534fdf3](534fdf3)), closes [#3753](#3753) [#3766](#3766) [#3769](#3769) [#3771](#3771) * **auth,admin:** move mailer warning to admin page, fix verify-email routing, align invite button ([0d195c4](0d195c4)) * **auth:** add missing $route.query mock in verifyEmail tests ([b2732f6](b2732f6)) * **auth:** address CodeRabbit review feedback ([1d14b06](1d14b06)) * **auth:** address review feedback from pass 1 ([bd27d2f](bd27d2f)) * **auth:** address review feedback from pass 1 ([a87fdb1](a87fdb1)) * **auth:** address review feedback from pass 2 — prevent form flash on load ([a6afeca](a6afeca)) * **auth:** fix runtime deprecation warnings and add auth view unit tests ([1901dad](1901dad)), closes [#3592](#3592) * **auth:** persist snackbar dismissal on implicit close ([5e464c3](5e464c3)) * **auth:** resolve lint errors and update test mocks for fetchServerConfig ([a642001](a642001)) * **billing:** add store unit tests and fix view import paths ([e370272](e370272)) * **billing:** address CodeRabbit review — guards, tests, JSDoc, price fallback ([f0f6657](f0f6657)) * **billing:** address CodeRabbit review feedback ([b195d2d](b195d2d)) * **billing:** address CodeRabbit review feedback ([8435d1c](8435d1c)) * **billing:** address CodeRabbit review feedback ([4187771](4187771)) * **billing:** address review — tier comparison, graceful failure, tests, naming ([7b00b91](7b00b91)) * **billing:** address review feedback — pricing card, fetch guard, router tests ([34cbda9](34cbda9)) * **billing:** address UI review findings ([b281a8a](b281a8a)) * **billing:** address UI review findings ([ead3eb0](ead3eb0)) * **billing:** address UI review findings ([b2d3897](b2d3897)) * **billing:** address UI review findings ([a756cd9](a756cd9)) * **billing:** align CASL guard subject with backend policy ([7e8287b](7e8287b)) * **billing:** align CASL guard subject with backend policy ([8e9b768](8e9b768)) * **billing:** correct plan field name, add enterprise badge, store cleanup ([#3733](#3733)) ([9b6e30d](9b6e30d)), closes [#3729](#3729) [#3730](#3730) [#3731](#3731) [#3732](#3732) [#3729](#3729) [#3730](#3730) [#3731](#3731) [#3732](#3732) * **billing:** correct test URL assertions to match store checkout URLs ([cd64628](cd64628)) * **billing:** correct view import paths to match lowercase filenames ([e2646dd](e2646dd)) * **billing:** default free plan display + E2E security tests ([#3751](#3751)) ([025534a](025534a)) * **billing:** fix branch coverage and E2E auth guard test ([2864cf7](2864cf7)) * **billing:** fix branch coverage and harden E2E auth test ([7b91edb](7b91edb)) * **billing:** fix error-handling tests and restore CASL guard on /billing route ([bcb15a6](bcb15a6)) * **billing:** fix plan merge — match by planId/name and build price objects ([1c1c765](1c1c765)) * **billing:** gate fetchSubscription behind org check and add missing [@returns](https://github.com/returns) JSDoc ([9dd15a7](9dd15a7)) * **billing:** harden URL validation, test assertions, and error handling ([44d9cc2](44d9cc2)) * **billing:** include canceled query param in checkout cancel URL ([9e28636](9e28636)) * **billing:** propagate errors, add CASL route metadata, rename views ([39343ba](39343ba)) * **billing:** remove duplicate import in E2E test ([02576f5](02576f5)) * **billing:** rename views, fix test assertions, address review feedback ([cb72130](cb72130)) * **billing:** separate checkout error from fetch error in pricing view ([78db8b1](78db8b1)) * **billing:** update store cancel URL to include canceled query param ([ca5f1a3](ca5f1a3)) * **billing:** validate portal URL and catch fetchSubscription rejection ([7534b6c](7534b6c)) * **ci:** ensure coverage thresholds pass with all modules ([8e0c970](8e0c970)), closes [#3710](#3710) * **ci:** remove ARC-specific conditionals from CI.yml ([#3806](#3806)) ([48747f3](48747f3)), closes [#3805](#3805) * **config:** add missing api section to config.test.js ([#3679](#3679)) ([fff9ffc](fff9ffc)), closes [#3676](#3676) * **config:** address review — use lodash-es, drop glob dep, add env warning ([1ec84fa](1ec84fa)) * **config:** address review feedback from pass 1 ([3336f09](3336f09)) * **config:** align app_title default between Dockerfile and hooks/build ([b08dbf3](b08dbf3)) * **config:** backward-compat fallback for sucessColor and improve warning ([1965557](1965557)) * **config:** fail fast when config is missing in production builds ([#3671](#3671)) ([c660ba4](c660ba4)), closes [#3669](#3669) * **config:** generateConfig ignores module env-specific configs ([#3827](#3827)) ([1ffd80e](1ffd80e)), closes [#3826](#3826) * **config:** remove [@desc](https://github.com/desc) tag from deepMerge JSDoc ([7c4b613](7c4b613)) * **config:** remove duplicate vuetify.theme block from app config merge ([5a583a7](5a583a7)) * **config:** remove unused imports and fix typo in generateConfig ([7b0c006](7b0c006)) * **config:** replace _.merge with deepMerge to fix array handling ([4e91025](4e91025)), closes [#3628](#3628) * **config:** skip undefined values and guard against prototype pollution in deepMerge ([ffc574e](ffc574e)) * **config:** use pathToFileURL for cross-platform dynamic imports ([acad44e](acad44e)) * **core:** address review feedback from pass 1 ([0f6e3af](0f6e3af)) * **core:** make datatable generic via fetchAction prop ([e3a4926](e3a4926)), closes [#3596](#3596) * **coverage:** exclude bootstrapper files with 0% coverage from collection ([4dfde5a](4dfde5a)) * **datatable:** increase per page select width to 100px ([#3779](#3779)) ([ff65d6f](ff65d6f)), closes [#3778](#3778) * **docker:** add DEVKIT_NODE_api_port to docker-compose.test.yml ([#3815](#3815)) ([0f06402](0f06402)), closes [#3809](#3809) * **docker:** make docker-compose.test.yml work for downstream projects ([#3790](#3790)) ([838aec1](838aec1)), closes [#3789](#3789) * **docs:** add src/ prefix and use <env> placeholder in merge order table ([5af5d5b](5af5d5b)) * **docs:** mark global env override config files as optional ([7459d0f](7459d0f)) * **e2e:** read ports from project config instead of hardcoding ([#3777](#3777)) ([ec56d20](ec56d20)), closes [#3775](#3775) * **header:** address review feedback from pass 1 ([b05d210](b05d210)) * **home,config:** address review feedback from pass 1 ([709ccbe](709ccbe)) * **home:** add JSDoc for tabs colorMode validator and tabStyle method ([a7fb5e3](a7fb5e3)) * **home:** add JSDoc to created() hook in home.team.view ([7548c15](7548c15)) * **home:** address CodeRabbit review feedback ([9990286](9990286)) * **home:** hero vertical centering, overlap prop, and Vuetify 4 typography migration ([4c26b25](4c26b25)), closes [#3587](#3587) * **home:** pass colorMode to tabs component so forced text color applies to tab items ([50256d8](50256d8)) * **lodash:** use lodash-es imports for proper tree-shaking ([50570cf](50570cf)) * **nav:** fix organizations ghost item icon in sidenav ([bca4237](bca4237)), closes [#3706](#3706) * **pull-request skill:** add consecutive_zero guard and re-check pending review checks ([18c70f8](18c70f8)) * **pull-request skill:** address review feedback — clarity and consistency ([2dd1ce2](2dd1ce2)) * **pull-request skill:** reply and resolve all threads including non-actionable ([ff776c8](ff776c8)) * **security:** harden auth views against XSS and weak validation ([#3735](#3735)) ([c3b844d](c3b844d)) * **seo-inject:** add JSON-LD structured data injection ([#3670](#3670)) ([5b36e5c](5b36e5c)), closes [#3664](#3664) * **seo:** improve heading hierarchy and alt text for accessibility ([#3661](#3661)) ([918f9bd](918f9bd)) * **seo:** puppeteer prerender Docker support + minor plugin fixes ([#3673](#3673)) ([8ac241b](8ac241b)) * **seo:** skip runtime JSON-LD when seo-inject handles schema ([#3677](#3677)) ([#3680](#3680)) ([b0d90ac](b0d90ac)) * **skill:** add merge conflict check in pull-request convergence loop ([ef136ed](ef136ed)), closes [#3707](#3707) * **skill:** address review feedback from pass 1 ([4020b82](4020b82)) * **skill:** handle CHANGES_REQUESTED, UNKNOWN mergeable, and standardize $PR usage ([13cb3cf](13cb3cf)) * **skill:** pull-request skill should ignore stack-level CodeRabbit comments for downstream projects ([97d2cb2](97d2cb2)), closes [#3604](#3604) * **skills:** clarify feature Phase 0 completeness check ([#3773](#3773)) ([8ac6b1b](8ac6b1b)) * **skills:** match coderabbitai[bot] login in monitoring jq filter ([aae850f](aae850f)) * **update-stack:** add concrete gh issue create command and resolution guidance ([6092368](6092368)) * **update-stack:** add downstream-only new files rule to conflict table ([4a15e39](4a15e39)) * **update-stack:** address review feedback from pass 1 ([f7ed820](f7ed820)) * **update-stack:** address review feedback from pass 2 ([2bef8a3](2bef8a3)) * **update-stack:** clarify failure origin criteria in step 3bis ([a71515e](a71515e)) ### Features * add /frontend design skill + migrate Vuetify 3 patterns to V4 ([#3644](#3644)) ([2f2a8ff](2f2a8ff)) * **analytics:** add useFeatureFlag and usePostHog composables ([#3774](#3774)) ([2506a4f](2506a4f)), closes [#3771](#3771) * **auth:** add email verification gate UI for org setup ([999aa60](999aa60)) * **auth:** add password visibility toggle ([#3752](#3752)) ([ea3b0a0](ea3b0a0)), closes [#336](#336) * **auth:** display server-side auth status on signin/signup pages ([0f4276d](0f4276d)) * **billing:** add billing page with plan badge and subscription management ([e9a1fc5](e9a1fc5)), closes [#3715](#3715) * **billing:** add BillingUsageBar component and enhance UpgradePrompt ([#3744](#3744)) ([0e9ca7f](0e9ca7f)) * **billing:** add checkout flow with auth/org guards and Stripe redirect ([ce17d67](ce17d67)), closes [#3714](#3714) * **billing:** add checkout flow with auth/org guards and Stripe redirect ([f762d91](f762d91)), closes [#3714](#3714) * **billing:** add feature gates — composable, upgrade prompt, router guard ([207c022](207c022)), closes [#3716](#3716) * **billing:** add homepage pricing section ([a8ced6d](a8ced6d)), closes [#3717](#3717) * **billing:** add pricing page with plan cards and billing toggle ([abb1d4a](abb1d4a)), closes [#3713](#3713) * **billing:** add pricing page with plan cards and billing toggle ([0881a9f](0881a9f)), closes [#3713](#3713) * **billing:** add useQuota composable for plan-based feature gating ([#3743](#3743)) ([85e2984](85e2984)) * **billing:** move pricing to dedicated page, update topnav ([eaab6f3](eaab6f3)) * **billing:** scaffold billing module with store, router, and views ([7b08b12](7b08b12)), closes [#3712](#3712) * **ci:** skip setup-node and playwright install on self-hosted runner ([#3803](#3803)) ([104d4f8](104d4f8)), closes [#3802](#3802) * **ci:** support configurable runner via RUNNER variable ([#3794](#3794)) ([1151d02](1151d02)), closes [#3792](#3792) * **ci:** use APP_ENV variable for generateConfig in CI ([#3801](#3801)) ([e384c7c](e384c7c)), closes [#3795](#3795) * **config:** migrate WAOS_VUE_* env prefix to DEVKIT_VUE_* ([7ad1a7f](7ad1a7f)), closes [#3614](#3614) * **header:** add float scroll behavior and document all config options ([d1d4891](d1d4891)) * **home:** add dedicated 404 Not Found page ([#3655](#3655)) ([ac73739](ac73739)) * **home:** add FAQ accordion component with JSON-LD schema ([#3821](#3821)) ([444e62c](444e62c)), closes [#3819](#3819) * **nav:** liquid glass sidenav with Apple-style inset mode ([#3737](#3737)) ([8203f2c](8203f2c)) * **pageHeader:** add tabs slot as alternative to icon + title ([#3781](#3781)) ([763d814](763d814)), closes [#3780](#3780) * phase 2 organizations ([#3702](#3702)) ([71c6a5c](71c6a5c)), closes [#3674](#3674) [#3675](#3675) [#3684](#3684) [#3686](#3686) [#3681](#3681) [#3682](#3682) [#3683](#3683) [#3684](#3684) [#3685](#3685) [#3686](#3686) [#3675](#3675) [#3674](#3674) * rename /frontend to /ui, add workflow rules ([#3704](#3704)) ([3d8259e](3d8259e)) * **sentry:** add Sentry error tracking and ErrorBoundary component ([#3788](#3788)) ([b5463d7](b5463d7)), closes [#3787](#3787) * **seo-inject:** add noscript fallback, preconnect hints, and theme-color ([#3663](#3663)) ([261a3a8](261a3a8)) * **seo:** add pre-rendering of home page at build time ([#3660](#3660)) ([39d9414](39d9414)) * **seo:** add seo-static Vite plugin for robots.txt, sitemap.xml, manifest.json ([#3658](#3658)) ([0a50388](0a50388)) * **update-stack:** report upstream issues when verify fails on stack code ([71dbecc](71dbecc)) * **verify:** add coverage enforcement to verify skill ([#3776](#3776)) ([63301f9](63301f9)) ### Performance Improvements * **ci:** optimize GitHub Actions ([#3793](#3793)) ([e31287e](e31287e)), closes [#3791](#3791)
Summary
Scope
homenonelowValidation
npm run lintnpm run test:unitnpm run buildGuardrails check
.env*,secrets/**, keys, tokens)Notes for reviewers