Skip to content

Next#160

Merged
markteekman merged 27 commits into
mainfrom
next
Sep 13, 2025
Merged

Next#160
markteekman merged 27 commits into
mainfrom
next

Conversation

@markteekman
Copy link
Copy Markdown
Member

@markteekman markteekman commented Sep 13, 2025

Summary by CodeRabbit

  • New Features

    • Added Contact, Thank-you, and Sitemap pages.
    • Introduced Featured Posts and Featured Projects sections.
    • Enabled sitemap.xml generation.
  • Refactor

    • Replaced anchors/headings with accessible Link/Heading components across pages and components.
    • Marked decorative icons aria-hidden; refreshed social share buttons.
    • Removed ExternalLink component in favor of unified Link.
  • Style

    • Adjusted navigation breakpoint to 1000px.
    • Updated card/link styling and various UI polish.
  • Documentation

    • Expanded README with WCAG 2.2 AA/EAA details, new features, and acknowledgements.
  • Chores

    • Bumped app version to 4.2.0 and updated dependencies.

…nd add author credit for the astronaut image
… improved navigation structure for enhanced accessibility
… and Link components for improved accessibility and semantic structure across multiple components and pages
…an Accessibility Act; enhance feature descriptions including new form validation components and sitemap generation
…and Header components to include links to the sitemap
…ved functionality and accessibility enhancements
@netlify
Copy link
Copy Markdown

netlify Bot commented Sep 13, 2025

Deploy Preview for accessible-astro-starter-incluud ready!

Name Link
🔨 Latest commit 13d9fbe
🔍 Latest deploy log https://app.netlify.com/projects/accessible-astro-starter-incluud/deploys/68c56070ea007d0008235986
😎 Deploy Preview https://deploy-preview-160--accessible-astro-starter-incluud.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.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Sep 13, 2025

Walkthrough

Introduces accessible Heading/Link usage across components/pages, adds FeaturedPosts/FeaturedProjects, new Contact/Thank-you/Sitemap pages, integrates @astrojs/sitemap, updates dependencies, adjusts a breakpoint, and removes ExternalLink. Several components receive accessibility tweaks (aria-hidden icons). Blog/Portfolio cards gain props; various styles cleaned or centralized.

Changes

Cohort / File(s) Summary of changes
Docs
README.md
Updated accessibility/compliance references, versions, components/pages overview, and credits.
Build/Config
astro.config.mjs, package.json
Added @astrojs/sitemap integration; bumped versions; updated deps incl. accessible-astro-components@^5, Tailwind 4.1, Astro 5.13; added @types/sanitize-html.
SCSS & Layout
src/assets/scss/base/_breakpoint.scss, src/layouts/DefaultLayout.astro
Nav breakpoint 900px→1000px; added global mixins import and link decoration for .card a.
Accessible components migration
src/components/CallToAction.astro, ColorContrast.astro, Feature.astro, Footer.astro, Header.astro, Hero.astro, Logo.astro, PageHeader.astro, SocialShares.astro, src/pages/404.astro, .../accessibility-statement.astro, .../color-contrast-checker.astro, .../blog/[post].astro, .../index.astro, .../portfolio/[project].astro
Replaced raw headings/anchors with Heading/Link; added aria-hidden to icons; updated nav items; adjusted structures accordingly.
ExternalLink removal
src/components/ExternalLink.astro
Deleted component; usages migrated to Link.
New feature components
src/components/FeaturedPosts.astro, src/components/FeaturedProjects.astro
Added sections rendering latest posts (remote fetch) and featured projects (content collections) with Cards and CTA Links.
BlockQuote accessibility
src/components/BlockQuote.astro
Marked decorative icons aria-hidden="true".
Content updates using BlockQuote
src/content/projects/project-0{2,3,4,5,6,7}.mdx
Replaced plain testimonials with BlockQuote component usage.
Cards and list pages
src/pages/blog/[...page].astro, src/pages/portfolio/[...page].astro
Passed headingLevel="h2" and fullHeight to Cards; removed local style blocks; simplified pagination vars in portfolio.
New pages
src/pages/contact.astro, src/pages/sitemap.astro, src/pages/thank-you.astro
Added Contact form page, human-readable Sitemap page, and Thank-you page; use accessible components throughout.
Sitemap notes
src/pages/sitemap.astro
Includes technical section referencing XML sitemap generated at build by plugin.
Minor content/icon tweaks
src/pages/mdx-page.mdx
Added aria-hidden to info icon.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor User
  participant ContactPage as Contact page
  participant A11yForm as Form (accessible-astro-components)
  participant Router as Astro Router
  participant ThankYou as Thank-you page

  User->>ContactPage: Navigate /contact
  ContactPage->>A11yForm: Render form with fields & validation attrs
  User->>A11yForm: Fill fields + Submit
  A11yForm-->>User: Client-side validation (WCAG 2.2 patterns)
  A11yForm->>Router: POST action="/thank-you"
  Router-->>ThankYou: Route render
  ThankYou-->>User: Display success message + CTA
Loading
sequenceDiagram
  autonumber
  participant Server as Astro (SSR/build)
  participant API as jsonplaceholder.typicode.com
  participant FeaturedPosts as FeaturedPosts.astro
  participant User as Browser

  Server->>FeaturedPosts: Render component
  FeaturedPosts->>API: GET /posts
  API-->>FeaturedPosts: JSON posts
  FeaturedPosts->>Server: HTML (Cards with images/links)
  Server-->>User: Deliver page with Featured posts
Loading
sequenceDiagram
  autonumber
  participant Build as Astro Build
  participant Plugin as @astrojs/sitemap
  participant FS as Filesystem

  Build->>Plugin: Initialize integrations
  Build->>Plugin: Provide routes/collections
  Plugin->>FS: Generate /sitemap.xml at build time
  FS-->>Build: Sitemap written
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related issues

  • incluud/accessible-astro-starter#152 — Implements adoption of a new accessible Link component and removes legacy ExternalLink across the codebase.

Possibly related PRs

Poem

A rabbit taps keys with a gentle clink,
Swapping links for Link with a cheerful wink.
Headings align, icons softly hide,
New pages hop in, side by side.
A sitemap blooms, stars align—
Ship it, sip tea, everything’s fine. 🐇✨

Pre-merge checks and finishing touches

❌ Failed checks (1 inconclusive)
Check name Status Explanation Resolution
Title Check ❓ Inconclusive The current title "Next" is a short, generic label that conveys no meaningful information about the substantive changes in this PR (dependency upgrades, sitemap integration, new contact/thank-you pages, FeaturedPosts/FeaturedProjects components, and broad accessible-component refactors across many files). Because it does not highlight the primary change or purpose, a teammate scanning history would not understand the main intent of this changeset. The title is therefore insufficient and inconclusive for review and changelog purposes. Please rename the PR to a concise, single-sentence title that highlights the main change (for example: "Add sitemap, contact form, FeaturedPosts/FeaturedProjects and upgrade dependencies for accessible components") and ensure the PR description summarizes the remaining details; if multiple equally important themes exist, choose the most impactful one for the title and list others in the description.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch next

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@markteekman markteekman merged commit a57f725 into main Sep 13, 2025
4 of 5 checks passed
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 9

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/pages/blog/[post].astro (1)

50-50: Fix typo in author bio.

“Pasionate” → “Passionate”.

-  bio: 'Pasionate accessibility advocate',
+  bio: 'Passionate accessibility advocate',
🧹 Nitpick comments (35)
src/components/BlockQuote.astro (2)

18-25: Wrap attribution in a footer for better blockquote semantics.

Using a <footer> around the <cite> aligns with HTML recommendations.

   <div>
     <Icon aria-hidden="true" name="lucide:quote" size="2rem" />
     <slot />
     <Icon aria-hidden="true" name="lucide:quote" size="2rem" />
   </div>
-  {author && <cite class="block text-sm font-medium">{author}</cite>}
+  {author && (
+    <footer>
+      <cite class="block text-sm font-medium not-italic">{author}</cite>
+    </footer>
+  )}

4-13: Remove unused children prop from Props.

Content is provided via <slot />; the children field isn’t referenced.

 interface Props {
-  /**
-   * The quote content that will be displayed
-   */
-  children: any
   /**
    * The name of the person who said the quote
    */
   author?: string
 }
src/pages/404.astro (1)

10-10: Make the H1 more descriptive for SRs.

Pure “404” can be ambiguous. Add hidden descriptive text.

-      <Heading level="h1">404</Heading>
+      <Heading level="h1">
+        <span class="sr-only">Page not found</span>
+        <span aria-hidden="true">404</span>
+      </Heading>
src/pages/accessibility-statement.astro (1)

81-84: Mark dates up with for better semantics.

Use machine-readable dates so tools can parse them.

-        This accessibility statement was prepared on <strong>[date]</strong> and last updated on <strong>[date]</strong>.
-        The website was last tested on
-        <strong>[latest test date]</strong> against WCAG 2.2 AA guidelines.
+        This accessibility statement was prepared on
+        <time datetime="[YYYY-MM-DD]">[date]</time> and last updated on
+        <time datetime="[YYYY-MM-DD]">[date]</time>. The website was last tested on
+        <time datetime="[YYYY-MM-DD]">[latest test date]</time> against WCAG 2.2 AA guidelines.
src/pages/blog/[...page].astro (1)

20-20: Tighten the featuredImage type.

Avoid any; prefer a concrete union matching Astro’s asset import.

-  featuredImage: any
+  featuredImage: ImageMetadata | string

Add the missing import at the top:

import type { ImageMetadata } from 'astro:assets'
src/components/Hero.astro (2)

29-38: Flag external GitHub button explicitly.

Set isExternal so Link applies external semantics (target/rel) consistently with the rest of the codebase.

-          <Link
+          <Link
             href="https://github.com/incluud/accessible-astro-starter"
             isButton
+            isExternal
             type="primary"
             animateOnHover
             animationType="boop"
           >

39-48: Do the same for the docs button.

-          <Link
+          <Link
             href="https://accessible-astro.incluud.dev/"
             isButton
+            isExternal
             type="secondary"
             animateOnHover
             animationType="boop"
           >
src/pages/portfolio/[...page].astro (1)

33-34: Narrow the featuredImage type on Props.

Avoid any to improve DX and catch mistakes early.

-interface Props {
-  page: Page<CollectionEntry<'projects'> & { featuredImage: any }>
-}
+interface Props {
+  page: Page<CollectionEntry<'projects'> & { featuredImage: ImageMetadata | string }>
+}

Add:

import type { ImageMetadata } from 'astro:assets'
src/components/CallToAction.astro (1)

38-41: Treat CTA link as external.

Add isExternal for consistent behavior and security headers.

-    <Link href={link} isButton size="lg" animateOnHover animationType="nudge">
+    <Link href={link} isButton isExternal size="lg" animateOnHover animationType="nudge">
src/components/Footer.astro (1)

84-96: Mark remaining external links as external for consistency.

These point off-site but lack isExternal; align them with the rest of the footer.

-        <p>Cute astronaut image by <Link href="https://unsplash.com/@kobbymendez">Kobby Mendez</Link> on Unsplash.</p>
+        <p>Cute astronaut image by <Link isExternal href="https://unsplash.com/@kobbymendez">Kobby Mendez</Link> on Unsplash.</p>
...
-        &copy; {currentYear} - Starter Theme for <Link href="https://astro.build/">Astro</Link>.
+        &copy; {currentYear} - Starter Theme for <Link isExternal href="https://astro.build/">Astro</Link>.
...
-        Made with ❤️ by <Link href="https://github.com/markteekman">Mark Teekman</Link>. Part of <Link
-          href="https://www.incluud.dev">Incluud</Link
+        Made with ❤️ by <Link isExternal href="https://github.com/markteekman">Mark Teekman</Link>. Part of <Link
+          isExternal href="https://www.incluud.dev">Incluud</Link
         >.
README.md (4)

7-7: Tighten wording and micro-grammar in the intro.

Consider minor clarity tweaks and parallel structure.

-A ready-to-use, SEO and accessibility-focused Astro starter template. Built with modern web standards, WCAG 2.2 AA guidelines, and European Accessibility Act (EAA) compliance in mind, it provides a solid foundation for creating inclusive websites. Features Tailwind CSS 4 integration, comprehensive component library with enhanced form validation, color contrast checker, and typography with Atkinson Hyperlegible font for improved readability. Includes dynamic blog/portfolio pages with social sharing, contact forms, and full MDX support.
+A ready-to-use, SEO- and accessibility-focused Astro starter template. Built with modern web standards, WCAG 2.2 AA guidelines, and European Accessibility Act (EAA) considerations in mind, it provides a solid foundation for creating inclusive websites. Features Tailwind CSS 4 integration, a comprehensive component library with enhanced form validation, a color-contrast checker, and typography using the Atkinson Hyperlegible font for improved readability. Includes dynamic blog/portfolio pages with social sharing, contact forms, and full MDX support.

28-28: Serial comma for consistency.

-- Semantic HTML structure with `Button`, `Link` and `Heading` components
+- Semantic HTML structure with `Button`, `Link`, and `Heading` components

52-54: Note on claims about sitemap and showcase pages looks accurate. Consider linking to the sitemap docs.

-- Comprehensive sitemap page with organized navigation and automatic XML sitemap generation via `@astrojs/sitemap`
+- Comprehensive sitemap page with organized navigation and automatic XML sitemap generation via `@astrojs/sitemap` (see docs)

19-21: Versions match — add automated README ↔ package.json self-check
package.json: Astro ^5.13.7, Tailwind CSS ^4.1.13; README.md (lines 19–20) lists Astro 5.13.0+ and Tailwind CSS 4.1+ — they align.
Add a small CI/npm script (e.g., jq + rg) to assert README values match package.json and fail CI on drift.

package.json (1)

1-15: Specify supported Node version to avoid CI/user surprises.

Astro 5 requires modern Node. Add engines.

{
  "engines": {
    "node": ">=20.10.0"
  }
}
src/components/Logo.astro (1)

2-2: Avoid duplicate announcement of brand name; make logo image decorative.

The link already contains the text “Accessible Astro”. Make the logo image alt-empty to prevent repetition for screen readers.

-  <Image src={logo} alt="Accessible Astro Logo" width="47" height="37" loading={loading} />
+  <Image src={logo} alt="" aria-hidden="true" width={47} height={37} loading={loading} />

Optional: when loading="eager", consider hinting priority:

-  <Image ... loading={loading} />
+  <Image ... loading={loading} fetchpriority={loading === 'eager' ? 'high' : 'auto'} />

Also applies to: 22-25

src/content/projects/project-05.mdx (1)

56-59: Optionally expose citation URL on BlockQuote.
If you have a source link for James Wu’s quote, consider a cite prop (or slot) to surface provenance.

src/content/projects/project-06.mdx (1)

56-59: Consider adding a cite/reference.
If a URL exists for this testimonial, wiring it through BlockQuote improves credibility.

src/content/projects/project-03.mdx (1)

56-59: Optional: include attribution link via cite prop.
Helps readers verify the testimonial.

src/components/FeaturedPosts.astro (3)

32-39: Tighten Post typing for images.
Use ImageMetadata instead of any.

Apply:

+import type { ImageMetadata } from 'astro:assets'
 ...
 interface Post {
   id: number
   userId: number
   title: string
   body: string
-  featuredImage: any
+  featuredImage: ImageMetadata
   shortUrl: string
 }

41-41: Guard and clamp limit.
Prevent 0/negative/huge values.

Apply:

-const { class: className, limit = 3, title = 'Latest posts' } = Astro.props
+const { class: className, limit = 3, title = 'Latest posts' } = Astro.props
+const resolvedLimit = Math.max(1, Math.min(Number(limit) || 3, 12))

And replace subsequent uses of limit with resolvedLimit.


87-90: Animation prop name likely inconsistent with other usage.
Elsewhere you use animation="boop"; here it’s animationType="nudge". Verify the API; if the prop is animation, update accordingly.

Apply (if needed):

-<Link href="/blog/" isButton animateOnHover animationType="nudge">
+<Link href="/blog/" isButton animateOnHover animation="nudge">
src/pages/contact.astro (1)

31-31: Phone pattern is strict; clarify formatting or sanitize input.
Pattern requires exactly 10 digits; typical users type separators (+, spaces, dashes). Either:

  • strip non-digits before validation, or
  • relax the pattern and explain accepted format via helper text.

Example relaxed pattern:

-<Input name="phone" label="Phone number" type="tel" required data-validation-pattern="^[0-9]{10}$" />
+<Input name="phone" label="Phone number" type="tel" required data-validation-pattern="^\D*?(\d\D*){10,15}$" />

And/or add helper copy and aria-describedby.

src/components/Header.astro (2)

26-31: Hook up dropdown button to its menu with aria-controls.

Tie the trigger and popup to improve semantics for AT and future scripting.

-      <button aria-haspopup="true" aria-expanded="false">
+      <button aria-haspopup="true" aria-expanded="false" aria-controls="theme-features-menu">
...
-      <ul class="dropdown-menu">
+      <ul id="theme-features-menu" class="dropdown-menu">

Ensure whatever toggles the dropdown also updates aria-expanded.


17-56: Be consistent with trailing slashes in internal URLs.

Mixed styles (/blog/ vs /accessibility-statement) can cause duplicate routes/canonicals depending on config.

Confirm your Astro trailingSlash setting; align links accordingly.

src/components/FeaturedProjects.astro (2)

35-43: Optional: filter drafts and sort by date before slicing.

Featured content should exclude drafts and be predictable.

-const projects = await getCollection('projects')
+const projects = await getCollection('projects', ({ data }) => !data.draft)
+  // newest first if date-like field exists; adjust field name as needed
+  .then(list => list.sort((a, b) => new Date(b.data.date ?? 0).getTime() - new Date(a.data.date ?? 0).getTime()))

Confirm your date field name (date, publishedAt, etc.).


52-61: Consider explicit alt text for card image.

If Card supports an imageAlt prop, wire it to the project title or a dedicated alt field.

Does Card accept imageAlt? If not, ignore.

src/pages/index.astro (2)

80-81: Trim stray whitespace in Icon size.

Minor nit: there’s a leading space in the size value.

-          <Icon aria-hidden="true" name="lucide:headset" size=" 1.5rem" />
+          <Icon aria-hidden="true" name="lucide:headset" size="1.5rem" />

123-125: Mark external W3C link explicitly.

If Link doesn’t auto-handle absolute URLs, add isExternal for correct rel/target.

-              established design patterns from the <Link href="https://www.w3.org/WAI/ARIA/apg/patterns/"
+              established design patterns from the <Link isExternal href="https://www.w3.org/WAI/ARIA/apg/patterns/"
                 >ARIA Authoring Practices Guide</Link
               >.
src/pages/accessible-components.astro (6)

569-579: Improve in-page nav accessibility with aria-current.

Set and clear aria-current="true" on the active link in addition to the CSS class.

-              if (link) {
-                navLinks.forEach((l) => l.classList.remove('active'))
-                link.classList.add('active')
-              }
+              if (link) {
+                navLinks.forEach((l) => {
+                  l.classList.remove('active')
+                  l.removeAttribute('aria-current')
+                })
+                link.classList.add('active')
+                link.setAttribute('aria-current', 'true')
+              }

Also initialize aria-current for the first observed section if needed.

Also applies to: 584-609


77-81: Avoid hash links that jump focus unexpectedly in demos.

href="#" can move focus to the top. Prefer buttons for demo actions.

Example:

-            <a href="#">Tab to me!</a>
+            <button type="button">Tab to me!</button>

Also applies to: 120-121, 519-520, 539-540, 553-554


161-164: Typo: “Astronout” → “Astronaut”.

User-facing copy.

-            label="Astronout"
+            label="Astronaut"

347-349: Use semantic input types and autocomplete.

Improve validation and UX.

-          <Input label="Email" required />
+          <Input label="Email" type="email" autocomplete="email" required />

Also consider autocomplete="name" on the Name field.


387-397: External-link demo should use an actual external URL.

Using / with isExternal will open your own home in a new tab. Prefer a true external example.

-        <Link href="/" isExternal>External link</Link>
+        <Link href="https://example.com" isExternal>External link</Link>

60-61: Add target="_blank" and rel="noopener noreferrer" to external anchors in the PageHeader subtitle (or refactor PageHeader to accept slots/Link).

PageHeader sanitizes subtitle HTML and allows a/target/rel attributes but doesn't inject them; update the anchors in src/pages/accessible-components.astro or refactor PageHeader to render Link components instead.

-      subtitle="This theme includes comprehensive accessibility components from the <a href='https://github.com/incluud/accessible-astro-components'>Accessible Astro Components</a> NPM package to accelerate accessible development. For detailed documentation and usage examples, visit our <a href='https://accessible-astro.incluud.dev/'>documentation website</a>. Additional components are available in the theme's components directory. Note: accessibility tools like aXe may report issues due to the static demonstration of the components on this page."
+      subtitle="This theme includes comprehensive accessibility components from the <a href='https://github.com/incluud/accessible-astro-components' target='_blank' rel='noopener noreferrer'>Accessible Astro Components</a> NPM package to accelerate accessible development. For detailed documentation and usage examples, visit our <a href='https://accessible-astro.incluud.dev/' target='_blank' rel='noopener noreferrer'>documentation website</a>. Additional components are available in the theme's components directory. Note: accessibility tools like aXe may report issues due to the static demonstration of the components on this page."
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 54ac758 and 13d9fbe.

⛔ Files ignored due to path filters (1)
  • public/social-preview-image.png is excluded by !**/*.png
📒 Files selected for processing (37)
  • README.md (4 hunks)
  • astro.config.mjs (2 hunks)
  • package.json (2 hunks)
  • src/assets/scss/base/_breakpoint.scss (1 hunks)
  • src/components/BlockQuote.astro (1 hunks)
  • src/components/CallToAction.astro (2 hunks)
  • src/components/ColorContrast.astro (5 hunks)
  • src/components/ExternalLink.astro (0 hunks)
  • src/components/Feature.astro (2 hunks)
  • src/components/FeaturedPosts.astro (1 hunks)
  • src/components/FeaturedProjects.astro (1 hunks)
  • src/components/Footer.astro (3 hunks)
  • src/components/Header.astro (2 hunks)
  • src/components/Hero.astro (2 hunks)
  • src/components/Logo.astro (2 hunks)
  • src/components/PageHeader.astro (2 hunks)
  • src/components/SocialShares.astro (2 hunks)
  • src/content/projects/project-02.mdx (2 hunks)
  • src/content/projects/project-03.mdx (2 hunks)
  • src/content/projects/project-04.mdx (2 hunks)
  • src/content/projects/project-05.mdx (2 hunks)
  • src/content/projects/project-06.mdx (2 hunks)
  • src/content/projects/project-07.mdx (2 hunks)
  • src/layouts/DefaultLayout.astro (2 hunks)
  • src/pages/404.astro (1 hunks)
  • src/pages/accessibility-statement.astro (4 hunks)
  • src/pages/accessible-components.astro (5 hunks)
  • src/pages/blog/[...page].astro (2 hunks)
  • src/pages/blog/[post].astro (6 hunks)
  • src/pages/color-contrast-checker.astro (2 hunks)
  • src/pages/contact.astro (1 hunks)
  • src/pages/index.astro (5 hunks)
  • src/pages/mdx-page.mdx (1 hunks)
  • src/pages/portfolio/[...page].astro (1 hunks)
  • src/pages/portfolio/[project].astro (3 hunks)
  • src/pages/sitemap.astro (1 hunks)
  • src/pages/thank-you.astro (1 hunks)
💤 Files with no reviewable changes (1)
  • src/components/ExternalLink.astro
🧰 Additional context used
🪛 ESLint
src/pages/thank-you.astro

[error] 4-4: 'Heading' is defined but never used.

(no-unused-vars)

🔇 Additional comments (43)
src/pages/mdx-page.mdx (1)

12-12: Decorative icon — good a11y improvement.

Marking the info icon aria-hidden="true" keeps SR focus on the message text. LGTM.

src/components/BlockQuote.astro (1)

20-23: Decorative quote icons — good.

Icons are correctly hidden from SRs while keeping the quote text readable.

src/pages/portfolio/[project].astro (3)

5-5: Accessible Heading import — good.

Consistent with the broader migration.


48-48: Verify url expects absolute vs relative.

If DefaultLayout uses url for canonical/OG tags, pass an absolute URL.

Possible fix if absolute is required:

-<DefaultLayout title={project.data.title} description={project.data.description} url={`/portfolio/${project.id}`}>
+<DefaultLayout
+  title={project.data.title}
+  description={project.data.description}
+  url={new URL(`/portfolio/${project.id}`, Astro.site).href}
+>

Please confirm how DefaultLayout consumes url.


63-63: Section heading via Heading — good.

Improves consistency and a11y.

astro.config.mjs (1)

8-15: Sitemap integration — good; confirm site is correct.

@astrojs/sitemap needs a correct site for canonical URLs. Double-check the domain/value for production.

src/assets/scss/base/_breakpoint.scss (1)

9-9: Verify Navigation usages after raising nav to 1000px

Found @include breakpoint('nav') in:

  • src/components/Navigation.astro:248 — desktop switch (.mobile-menu { display: none; }) — confirm menu toggle behavior between 900–1024px.
  • src/components/Navigation.astro:405 — alignment (margin-block-start: 7px) — confirm spacing/alignment between 900–1024px.

Validate visually (responsive inspector) across 900–1024px.

src/components/Feature.astro (1)

2-2: Accessible icon + Heading component — solid.

Icons are decorative; headings standardized. Looks good.

Also applies to: 25-25, 27-27

src/pages/404.astro (1)

16-19: Button-like Link + decorative icon — good.

Clear call-to-action, icon hidden from SRs. LGTM.

src/pages/blog/[post].astro (3)

6-6: Heading import — good.

Consistent with the a11y component approach.


69-69: Headings migrated to Heading — good.

Improves semantic consistency across the page.

Also applies to: 111-111, 123-123, 132-132, 143-143


76-104: Confirm image alt usage.

Empty alt hides images from SRs. If these images are informative (not purely decorative), provide meaningful alt text.

src/pages/accessibility-statement.astro (1)

15-15: Good semantic upgrade to structured section headings.

Using for all sections is consistent with PageHeader’s h1. Nice.

Also applies to: 23-23, 30-30, 47-47, 53-53, 65-65, 73-73, 79-79

src/pages/blog/[...page].astro (1)

77-80: Card props for heading level and fullHeight look correct.

Matches the pattern used on portfolio; improves semantics and consistent card heights.

src/components/SocialShares.astro (1)

21-34: Solid a11y details on the share buttons.

Good use of isExternal, sr-only labels, and aria-hidden icons.

Also applies to: 48-61

src/pages/portfolio/[...page].astro (1)

59-62: Card props LGTM.

Consistent with blog cards and improves semantics/layout.

src/components/PageHeader.astro (1)

2-2: Heading component adoption looks good.

Using for the page title aligns with the new site-wide pattern.

Also applies to: 108-108

README.md (1)

101-101: Attribution LGTM.

package.json (2)

37-66: Approve changes — verify accessible-astro-components v5 migration

Ran the checks across src/**: no ExternalLink matches and no imports of Link/Heading from 'accessible-astro-components' were found; many occurrences exist.

  • Action: Verify MDX and any non-src or dynamic imports for Link/Heading/ExternalLink usages and migrate to v5 APIs if present.

57-60: Potential misclassification: sanitize-html is in devDependencies — move to dependencies if used at runtime

package.json currently lists sanitize-html (^2.17.0) and @types/sanitize-html (^2.13.0) under devDependencies (package.json). Confirm whether sanitize-html is imported/required in server/SSR/request-handling code; if so, move it to dependencies and keep @types/sanitize-html in devDependencies.

Suggested change:

   "devDependencies": {
-    "sanitize-html": "^2.17.0",
   },
   "dependencies": {
+    "sanitize-html": "^2.17.0",
   }
src/pages/color-contrast-checker.astro (1)

5-5: Switch to Heading component is consistent and improves semantics.

Hierarchy remains correct under PageHeader’s h1.

Also applies to: 17-17

src/content/projects/project-02.mdx (1)

11-11: Good move to BlockQuote for testimonials; improves semantics and reuse.

Also applies to: 56-59

src/layouts/DefaultLayout.astro (1)

39-41: Mixin present; no button-like anchors found — optional scoping suggested.

  • @mixin text-decoration is defined at src/assets/scss/base/_mixins.scss.
  • No occurrences of .btn, role="button", or data-variant="button" found in src/**; .card a therefore won't currently restyle button-like links.
  • Optional (safe) tweak if you want to protect future button-links: .card a:not(.btn, [role="button"]) { @include text-decoration(transparent, var(--foreground-color), 4px, 2px); }
src/content/projects/project-07.mdx (1)

11-11: BlockQuote adoption LGTM.

Also applies to: 56-59

src/content/projects/project-04.mdx (1)

11-11: Consistent testimonial semantics via BlockQuote—nice.

Also applies to: 56-59

src/content/projects/project-05.mdx (1)

11-11: Consistent testimonial component import — looks good.

src/content/projects/project-06.mdx (1)

11-11: Good move to centralize testimonial styling via BlockQuote.

src/content/projects/project-03.mdx (1)

11-11: Import aligns with the shared testimonial pattern.

src/components/ColorContrast.astro (3)

8-8: Heading import aligns with the codebase’s accessible heading strategy.


68-68: Heading replacements improve semantics; confirm rendered tags match CSS expectations.
Assuming Heading renders actual h2/h3 elements, existing CSS continues to apply. If it renders divs with roles, update selectors accordingly.

Also applies to: 74-74, 93-93, 112-112


277-279: Scoped CSS update is correct.
Grouping h2/h3 keeps spacing consistent after the Heading switch.

src/pages/thank-you.astro (1)

16-19: Verify Link animation prop name.
Elsewhere you use animation="boop"; here that’s consistent. Just ensure pulse respects prefers-reduced-motion (handled in the lib).

src/components/FeaturedPosts.astro (1)

75-82: Confirm Card supports alt text for the image.
If Card doesn’t provide a meaningful alt, pass one explicitly or expose an imageAlt prop to avoid decorative images reading poorly.

src/pages/sitemap.astro (1)

173-176: Verify @astrojs/sitemap is actually enabled.
Since the page references it, ensure astro.config.mjs includes sitemap() and site URL is set; otherwise /sitemap.xml won’t be emitted.

src/components/Header.astro (4)

3-3: Nice: consolidated imports and Link adoption.

Importing Link alongside DarkMode and SkipLink keeps the header consistent with the new component library usage.


28-29: Good a11y: decorative icons are hidden from AT.

aria-hidden="true" on chevron, GitHub, moon, and sun icons is correct for non-textual ornamentation.

Also applies to: 61-63, 68-69


49-52: Sitemap menu item: confirm destination.

If this is a human-readable page (/sitemap), great. If you intend the XML sitemap from @astrojs/sitemap, that’s usually /sitemap-index.xml or /sitemap.xml.


58-59: Mark external links explicitly — add isExternal to Link.

If your Link component doesn't auto-detect absolute URLs it may omit target/rel. Make intent explicit.

File: src/components/Header.astro (lines 58–59, also 61–65)
Suggested change:

  • Docs
src/components/FeaturedProjects.astro (2)

54-55: Use slug for public portfolio URLs (not id)

project.id is used throughout routing/sitemap; switch to project.slug and update routing/getStaticPaths accordingly.

-            url={'/portfolio/' + project.id}
+            url={'/portfolio/' + project.slug + '/'}

Update these locations: src/components/FeaturedProjects.astro, src/pages/portfolio/[project].astro, src/pages/portfolio/[...page].astro, src/pages/sitemap.astro. Verify src/content.config.ts (or entry frontmatter) provides a usable slug before changing.


53-57: No change required — Card supports imageComponent.

The Card component accepts both img and imageComponent (ImageMetadata or dynamic import), so imageComponent={project.featuredImage} is valid. (accessible-astro.incluud.dev)

src/pages/index.astro (1)

17-18: Headings migration looks good.

Consistent Heading usage improves structure and theming.

Also applies to: 52-53, 62-68, 154-155

src/pages/accessible-components.astro (2)

437-438: Unresolved closeModal() — don’t call a global; use the Modal API or add a local handler.

No closeModal() definition found in the repo; accessible-astro-components is listed in package.json but not present in node_modules here, so a global cannot be assumed.
File: src/pages/accessible-components.astro:437-438

          <button class="button" onclick="closeModal()">Confirm action</button>
        </Modal>

Replace the inline onclick call with the Modal component's documented close/slot API or wire a local JS function that closes the modal instance instead of relying on a global.


492-495: Pass numbers as numbers — use a numeric literal for totalPages.

File: src/pages/accessible-components.astro (lines 492–495)

-        <Pagination totalPages="200" />
+        <Pagination totalPages={200} />

Confirm prop type in the Pagination component API — Pagination is imported from 'accessible-astro-components' and its implementation isn't in this repo.

Comment on lines +43 to +46
// Fetch posts from API
const response = await fetch('https://jsonplaceholder.typicode.com/posts')
const data = await response.json()

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add fetch error handling and a timeout to avoid SSR build hangs.
Currently a network stall will tank the page build.

Apply:

-const response = await fetch('https://jsonplaceholder.typicode.com/posts')
-const data = await response.json()
+const controller = new AbortController()
+const timeout = setTimeout(() => controller.abort(), 5000)
+let data: any[] = []
+try {
+  const response = await fetch('https://jsonplaceholder.typicode.com/posts', { signal: controller.signal })
+  if (!response.ok) throw new Error(`HTTP ${response.status}`)
+  data = await response.json()
+} catch (e) {
+  data = []
+  console.warn('FeaturedPosts: falling back due to fetch error:', e)
+} finally {
+  clearTimeout(timeout)
+}

Optionally render a graceful empty-state when data.length === 0.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// Fetch posts from API
const response = await fetch('https://jsonplaceholder.typicode.com/posts')
const data = await response.json()
// Fetch posts from API
const controller = new AbortController()
const timeout = setTimeout(() => controller.abort(), 5000)
let data: any[] = []
try {
const response = await fetch('https://jsonplaceholder.typicode.com/posts', { signal: controller.signal })
if (!response.ok) throw new Error(`HTTP ${response.status}`)
data = await response.json()
} catch (e) {
data = []
console.warn('FeaturedPosts: falling back due to fetch error:', e)
} finally {
clearTimeout(timeout)
}
🤖 Prompt for AI Agents
In src/components/FeaturedPosts.astro around lines 43 to 46, the fetch has no
timeout or error handling which can hang SSR builds; wrap the fetch in a
try/catch, use an AbortController with a short timeout (e.g., 5s) to abort
stalled requests, check response.ok before calling response.json(), and on any
error or non-OK response return an empty array fallback; then ensure the
template optionally renders a graceful empty-state when data.length === 0 (e.g.,
show a placeholder message or skip the posts list).

Comment on lines +57 to +65
const featuredPosts: Post[] = data.slice(0, limit).map((post: any) => {
const truncatedTitle = truncateTitle(post.title)
return {
...post,
featuredImage: postImages[post.id % postImages.length],
title: truncatedTitle,
shortUrl: truncatedTitle.replaceAll(' ', '-').toLowerCase(),
}
})
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Stabilize image selection and slug generation.

  • Use map index for deterministic image rotation.
  • Replace naive replaceAll with a slugify to avoid punctuation/duplicate issues.

Apply:

-const featuredPosts: Post[] = data.slice(0, limit).map((post: any) => {
-  const truncatedTitle = truncateTitle(post.title)
-  return {
-    ...post,
-    featuredImage: postImages[post.id % postImages.length],
-    title: truncatedTitle,
-    shortUrl: truncatedTitle.replaceAll(' ', '-').toLowerCase(),
-  }
-})
+function slugify(input: string): string {
+  return input
+    .toLowerCase()
+    .normalize('NFKD')
+    .replace(/[\u0300-\u036f]/g, '') // strip diacritics
+    .replace(/[^a-z0-9]+/g, '-')     // non-alphanum -> hyphen
+    .replace(/^-+|-+$/g, '')         // trim hyphens
+}
+
+const featuredPosts: Post[] = data.slice(0, resolvedLimit).map((post: any, i: number) => {
+  const truncatedTitle = truncateTitle(post.title)
+  return {
+    ...post,
+    featuredImage: postImages[i % postImages.length],
+    title: truncatedTitle,
+    shortUrl: slugify(truncatedTitle),
+  }
+})

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In src/components/FeaturedPosts.astro around lines 57 to 65, replace the current
image selection and naive slug generation: use the map callback index (i) to
choose images deterministically (e.g., postImages[i % postImages.length])
instead of post.id, and replace truncatedTitle.replaceAll(' ', '-') with a
proper slugify step (import or local slugify helper) that lowercases, strips
punctuation, collapses consecutive non-alphanumerics into single hyphens, and
trims leading/trailing hyphens to avoid duplicates and invalid characters.

Comment on lines +22 to 29
<li><Link href="/accessibility-statement">Accessibility statement</Link></li>
<li><Link href="/accessible-components">Accessible components</Link></li>
<li><Link href="/color-contrast-checker">Color contrast checker</Link></li>
<li><Link href="/markdown-page">Markdown page</Link></li>
<li><Link href="/mdx-page">MDX page</Link></li>
<li><Link href="/404-page">404 page</Link></li>
<li><Link href="/sitemap">Sitemap</Link></li>
</ul>
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Broken link: 404 page route.

The site’s 404 route is typically /404 (and this repo has src/pages/404.astro). /404-page will 404.

-          <li><Link href="/404-page">404 page</Link></li>
+          <li><Link href="/404">404 page</Link></li>

🏁 Script executed:

#!/usr/bin/env bash
# Verify which 404 page exists and check for any '/404-page' links.
fd -a --strip-cwd-prefix -t f '404*.astro' src/pages | sed 's/^/FOUND: /'
rg -n --glob '!**/node_modules/**' '/404-page\b' -S -g '!**/dist/**'

Length of output: 340


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail
echo "== Files named 404.astro under src/pages =="
rg --files -g 'src/pages/**/404.astro' || true

echo
echo "== Any '/404-page' occurrences =="
rg -n --hidden --glob '!**/node_modules/**' --glob '!**/dist/**' '/404-page\b' || true

echo
echo "== Any '/404' occurrences =="
rg -n --hidden --glob '!**/node_modules/**' --glob '!**/dist/**' '/404\b' || true

Length of output: 426


Fix broken 404 link — use /404

src/pages/404.astro exists; /404-page will 404.

File: src/components/Footer.astro (lines 22-29)

-          <li><Link href="/404-page">404 page</Link></li>
+          <li><Link href="/404">404 page</Link></li>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<li><Link href="/accessibility-statement">Accessibility statement</Link></li>
<li><Link href="/accessible-components">Accessible components</Link></li>
<li><Link href="/color-contrast-checker">Color contrast checker</Link></li>
<li><Link href="/markdown-page">Markdown page</Link></li>
<li><Link href="/mdx-page">MDX page</Link></li>
<li><Link href="/404-page">404 page</Link></li>
<li><Link href="/sitemap">Sitemap</Link></li>
</ul>
<li><Link href="/accessibility-statement">Accessibility statement</Link></li>
<li><Link href="/accessible-components">Accessible components</Link></li>
<li><Link href="/color-contrast-checker">Color contrast checker</Link></li>
<li><Link href="/markdown-page">Markdown page</Link></li>
<li><Link href="/mdx-page">MDX page</Link></li>
<li><Link href="/404">404 page</Link></li>
<li><Link href="/sitemap">Sitemap</Link></li>
</ul>
🤖 Prompt for AI Agents
In src/components/Footer.astro around lines 22 to 29, the link currently points
to "/404-page" which does not exist; update the href to "/404" so it correctly
routes to the existing src/pages/404.astro page; ensure the Link text can remain
"404 page" or be adjusted for clarity, and run the dev server to verify the
footer link now resolves to /404.

Comment on lines +36 to +46
<Link
href={`https://x.com/share?url=${encodeURIComponent(url)}`}
isButton
isExternal
hideIcon
animateOnHover
animationType="boop"
>
<Icon aria-hidden="true" name="lucide:twitter" size={32} />
<span class="sr-only">Share on Twitter, opens in a new tab</span>
</Link>
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix X/Twitter share endpoint (use Web Intent).

Use the documented Web Intent endpoint; the current x.com/share URL is unreliable.

-    <Link
-      href={`https://x.com/share?url=${encodeURIComponent(url)}`}
+    <Link
+      href={`https://twitter.com/intent/tweet?url=${encodeURIComponent(url)}`}
       isButton
       isExternal
       hideIcon
       animateOnHover
       animationType="boop"
     >

This follows X’s official guidance for tweet composition links. (developer.x.com)

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<Link
href={`https://x.com/share?url=${encodeURIComponent(url)}`}
isButton
isExternal
hideIcon
animateOnHover
animationType="boop"
>
<Icon aria-hidden="true" name="lucide:twitter" size={32} />
<span class="sr-only">Share on Twitter, opens in a new tab</span>
</Link>
<Link
href={`https://twitter.com/intent/tweet?url=${encodeURIComponent(url)}`}
isButton
isExternal
hideIcon
animateOnHover
animationType="boop"
>
<Icon aria-hidden="true" name="lucide:twitter" size={32} />
<span class="sr-only">Share on Twitter, opens in a new tab</span>
</Link>
🤖 Prompt for AI Agents
In src/components/SocialShares.astro around lines 36 to 46, the share link uses
the unreliable x.com/share endpoint; replace it with the documented Web Intent
endpoint (e.g. https://twitter.com/intent/tweet) and construct the query with
encodeURIComponent(url) (or compose text + url as needed) so the Link href
becomes the Web Intent URL (https://twitter.com/intent/tweet?url=... or
?text=...), preserving isButton/isExternal/hideIcon/animateOnHover and
accessibility span.

Comment on lines +372 to +380
<p>Headings are used to structure the content of a page. They should be used in the following order:</p>
<div class="flex-col flex-wrap gap-4">
<Heading level="h1">Heading 1</Heading>
<Heading level="h2">Heading 2</Heading>
<Heading level="h3">Heading 3</Heading>
<Heading level="h4">Heading 4</Heading>
<Heading level="h5">Heading 5</Heading>
<Heading level="h6">Heading 6</Heading>
</div>
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Missing Tailwind utility: add flex.

flex-col without flex won’t apply layout.

-        <div class="flex-col flex-wrap gap-4">
+        <div class="flex flex-col flex-wrap gap-4">
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<p>Headings are used to structure the content of a page. They should be used in the following order:</p>
<div class="flex-col flex-wrap gap-4">
<Heading level="h1">Heading 1</Heading>
<Heading level="h2">Heading 2</Heading>
<Heading level="h3">Heading 3</Heading>
<Heading level="h4">Heading 4</Heading>
<Heading level="h5">Heading 5</Heading>
<Heading level="h6">Heading 6</Heading>
</div>
<p>Headings are used to structure the content of a page. They should be used in the following order:</p>
<div class="flex flex-col flex-wrap gap-4">
<Heading level="h1">Heading 1</Heading>
<Heading level="h2">Heading 2</Heading>
<Heading level="h3">Heading 3</Heading>
<Heading level="h4">Heading 4</Heading>
<Heading level="h5">Heading 5</Heading>
<Heading level="h6">Heading 6</Heading>
</div>
🤖 Prompt for AI Agents
In src/pages/accessible-components.astro around lines 372 to 380, the container
div uses the Tailwind class "flex-col" but is missing the base "flex" utility so
the flex layout won't be applied; update the div's class list to include "flex"
(e.g., "flex flex-col flex-wrap gap-4") to ensure the column flex layout is
activated while preserving the other utilities.

Comment thread src/pages/contact.astro
Comment on lines +36 to +46
<Fieldset
name="interests"
legend="What are you interested in?"
required
data-validation="Please select at least one area of interest"
>
<Checkbox name="accessibility" value="a11y" label="Accessibility and inclusive design" />
<Checkbox name="wcag-compliance" value="wcag" label="WCAG compliance and testing" />
<Checkbox name="screen-reader" value="sr" label="Screen reader optimization" />
<Checkbox name="keyboard-nav" value="keyboard" label="Keyboard navigation" />
</Fieldset>
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Checkbox group won’t validate as a set.
All checkboxes in a required group must share the same name to satisfy group-level validation. Currently they each have unique names, so Fieldset required won’t work.

Apply:

-<Fieldset
-  name="interests"
+<Fieldset
+  name="interests"
   legend="What are you interested in?"
   required
   data-validation="Please select at least one area of interest"
 >
-  <Checkbox name="accessibility" value="a11y" label="Accessibility and inclusive design" />
-  <Checkbox name="wcag-compliance" value="wcag" label="WCAG compliance and testing" />
-  <Checkbox name="screen-reader" value="sr" label="Screen reader optimization" />
-  <Checkbox name="keyboard-nav" value="keyboard" label="Keyboard navigation" />
+  <Checkbox name="interests" value="a11y" label="Accessibility and inclusive design" />
+  <Checkbox name="interests" value="wcag" label="WCAG compliance and testing" />
+  <Checkbox name="interests" value="sr" label="Screen reader optimization" />
+  <Checkbox name="interests" value="keyboard" label="Keyboard navigation" />
 </Fieldset>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<Fieldset
name="interests"
legend="What are you interested in?"
required
data-validation="Please select at least one area of interest"
>
<Checkbox name="accessibility" value="a11y" label="Accessibility and inclusive design" />
<Checkbox name="wcag-compliance" value="wcag" label="WCAG compliance and testing" />
<Checkbox name="screen-reader" value="sr" label="Screen reader optimization" />
<Checkbox name="keyboard-nav" value="keyboard" label="Keyboard navigation" />
</Fieldset>
<Fieldset
name="interests"
legend="What are you interested in?"
required
data-validation="Please select at least one area of interest"
>
<Checkbox name="interests" value="a11y" label="Accessibility and inclusive design" />
<Checkbox name="interests" value="wcag" label="WCAG compliance and testing" />
<Checkbox name="interests" value="sr" label="Screen reader optimization" />
<Checkbox name="interests" value="keyboard" label="Keyboard navigation" />
</Fieldset>
🤖 Prompt for AI Agents
In src/pages/contact.astro around lines 36 to 46, the Fieldset is marked
required but each Checkbox uses a unique name so browser/group validation won't
detect a selected box; change all Checkbox name attributes to match the Fieldset
name (e.g., name="interests") and keep distinct value attributes for each option
so the group validates as a single required field while still submitting
individual values.

Comment thread src/pages/contact.astro
Comment on lines +102 to +121
<ul class="flex flex-wrap gap-2">
<li>
<Link href="/" isButton isExternal hideIcon animateOnHover animationType="boop">
<Icon aria-hidden="true" name="lucide:facebook" size={32} />
<span class="sr-only">Go to our Facebook page, opens in a new tab</span>
</Link>
</li>
<li>
<Link href="/" isButton isExternal hideIcon animateOnHover animationType="boop">
<Icon aria-hidden="true" name="lucide:twitter" size={32} />
<span class="sr-only">Go to our Twitter page, opens in a new tab</span>
</Link>
</li>
<li>
<Link href="/" isButton isExternal hideIcon animateOnHover animationType="boop">
<Icon aria-hidden="true" name="lucide:linkedin" size={32} />
<span class="sr-only">Go to our LinkedIn page, opens in a new tab</span>
</Link>
</li>
</ul>
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Social links point to “/” but announce external new-tab behavior.
This is misleading. Either use real external URLs or remove isExternal and update the SR text.

Apply one of:

-<Link href="/" isButton isExternal hideIcon animateOnHover animationType="boop">
+<Link href="https://facebook.com/your-handle" isButton isExternal hideIcon animateOnHover animationType="boop">

or:

-<Link href="/" isButton isExternal hideIcon animateOnHover animationType="boop">
+<Link href="/" isButton hideIcon animateOnHover animationType="boop">
 ...
-  <span class="sr-only">Go to our Facebook page, opens in a new tab</span>
+  <span class="sr-only">Go to our Facebook page</span>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<ul class="flex flex-wrap gap-2">
<li>
<Link href="/" isButton isExternal hideIcon animateOnHover animationType="boop">
<Icon aria-hidden="true" name="lucide:facebook" size={32} />
<span class="sr-only">Go to our Facebook page, opens in a new tab</span>
</Link>
</li>
<li>
<Link href="/" isButton isExternal hideIcon animateOnHover animationType="boop">
<Icon aria-hidden="true" name="lucide:twitter" size={32} />
<span class="sr-only">Go to our Twitter page, opens in a new tab</span>
</Link>
</li>
<li>
<Link href="/" isButton isExternal hideIcon animateOnHover animationType="boop">
<Icon aria-hidden="true" name="lucide:linkedin" size={32} />
<span class="sr-only">Go to our LinkedIn page, opens in a new tab</span>
</Link>
</li>
</ul>
<ul class="flex flex-wrap gap-2">
<li>
<Link href="https://facebook.com/your-handle" isButton isExternal hideIcon animateOnHover animationType="boop">
<Icon aria-hidden="true" name="lucide:facebook" size={32} />
<span class="sr-only">Go to our Facebook page, opens in a new tab</span>
</Link>
</li>
<li>
<Link href="https://twitter.com/your-handle" isButton isExternal hideIcon animateOnHover animationType="boop">
<Icon aria-hidden="true" name="lucide:twitter" size={32} />
<span class="sr-only">Go to our Twitter page, opens in a new tab</span>
</Link>
</li>
<li>
<Link href="https://linkedin.com/in/your-handle" isButton isExternal hideIcon animateOnHover animationType="boop">
<Icon aria-hidden="true" name="lucide:linkedin" size={32} />
<span class="sr-only">Go to our LinkedIn page, opens in a new tab</span>
</Link>
</li>
</ul>
Suggested change
<ul class="flex flex-wrap gap-2">
<li>
<Link href="/" isButton isExternal hideIcon animateOnHover animationType="boop">
<Icon aria-hidden="true" name="lucide:facebook" size={32} />
<span class="sr-only">Go to our Facebook page, opens in a new tab</span>
</Link>
</li>
<li>
<Link href="/" isButton isExternal hideIcon animateOnHover animationType="boop">
<Icon aria-hidden="true" name="lucide:twitter" size={32} />
<span class="sr-only">Go to our Twitter page, opens in a new tab</span>
</Link>
</li>
<li>
<Link href="/" isButton isExternal hideIcon animateOnHover animationType="boop">
<Icon aria-hidden="true" name="lucide:linkedin" size={32} />
<span class="sr-only">Go to our LinkedIn page, opens in a new tab</span>
</Link>
</li>
</ul>
<ul class="flex flex-wrap gap-2">
<li>
<Link href="/" isButton hideIcon animateOnHover animationType="boop">
<Icon aria-hidden="true" name="lucide:facebook" size={32} />
<span class="sr-only">Go to our Facebook page</span>
</Link>
</li>
<li>
<Link href="/" isButton hideIcon animateOnHover animationType="boop">
<Icon aria-hidden="true" name="lucide:twitter" size={32} />
<span class="sr-only">Go to our Twitter page</span>
</Link>
</li>
<li>
<Link href="/" isButton hideIcon animateOnHover animationType="boop">
<Icon aria-hidden="true" name="lucide:linkedin" size={32} />
<span class="sr-only">Go to our LinkedIn page</span>
</Link>
</li>
</ul>
🤖 Prompt for AI Agents
In src/pages/contact.astro around lines 102 to 121 the social Link components
point to "/" while the props and SR text claim they are external and open in a
new tab, which is misleading; fix by either (A) replacing the hrefs with the
actual external URLs for Facebook/Twitter/LinkedIn and keep isExternal plus the
SR text (and ensure the Link adds target="_blank" and rel="noopener
noreferrer"), or (B) remove the isExternal prop and change each sr-only text to
say “Go to our [site name] page” without mentioning a new tab so the
accessibility text matches behavior.

Comment thread src/pages/index.astro
Comment on lines +79 to +82
<Link href="/faq" isButton type="primary" animateOnHover animationType="boop">
<Icon aria-hidden="true" name="lucide:headset" size=" 1.5rem" />
Contact support team
</Link>
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

CTA label/URL mismatch.

“Contact support team” points to /faq. Either change the label or link to /contact/.

-        <Link href="/faq" isButton type="primary" animateOnHover animationType="boop">
+        <Link href="/contact/" isButton type="primary" animateOnHover animationType="boop">
           <Icon aria-hidden="true" name="lucide:headset" size=" 1.5rem" />
           Contact support team
         </Link>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<Link href="/faq" isButton type="primary" animateOnHover animationType="boop">
<Icon aria-hidden="true" name="lucide:headset" size=" 1.5rem" />
Contact support team
</Link>
<Link href="/contact/" isButton type="primary" animateOnHover animationType="boop">
<Icon aria-hidden="true" name="lucide:headset" size=" 1.5rem" />
Contact support team
</Link>
🤖 Prompt for AI Agents
In src/pages/index.astro around lines 79 to 82 the CTA label "Contact support
team" points to /faq which is a mismatch; update the component so the label and
URL match — either change href="/faq" to href="/contact/" (preferred if this
button should open the contact page) or change the visible text to something
like "Read our FAQ" if it should keep linking to /faq; ensure URL uses trailing
slash consistent with project routing and adjust any accessibility text if
present.

Comment thread src/pages/thank-you.astro
---
import DefaultLayout from '@layouts/DefaultLayout.astro'
import PageHeader from '@components/PageHeader.astro'
import { Heading, Link, Notification } from 'accessible-astro-components'
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Remove unused Heading import to satisfy no-unused-vars.
This will break CI as an error; drop it.

Apply:

-import { Heading, Link, Notification } from 'accessible-astro-components'
+import { Link, Notification } from 'accessible-astro-components'
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
import { Heading, Link, Notification } from 'accessible-astro-components'
import { Link, Notification } from 'accessible-astro-components'
🧰 Tools
🪛 ESLint

[error] 4-4: 'Heading' is defined but never used.

(no-unused-vars)

🤖 Prompt for AI Agents
In src/pages/thank-you.astro around line 4, the import statement includes an
unused Heading symbol which triggers a no-unused-vars CI error; remove Heading
from the import so it reads only the used components (e.g., import { Link,
Notification } from 'accessible-astro-components') and save the file to resolve
the lint/CI failure.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant