Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
ac344c6
feat: implement new design & dark mode on Docs and Homepage (#4424)
Shriya-Chauhan Oct 8, 2025
dcba9ae
Merge branch 'master' into website-ui
akshatnema Oct 16, 2025
702e050
fix: improved homepage and docs layout and added missing details to t…
Shriya-Chauhan Nov 14, 2025
dee1e65
Merge branch 'master' into website-ui
princerajpoot20 Dec 30, 2025
7bf9bb5
feat: adding casestudies, blogs, tsc, roadmap, events, ambassadors pa…
Shriya-Chauhan Feb 4, 2026
202143b
chore: resolve dark theme merge conflicts (#5354)
princerajpoot20 Apr 22, 2026
930a6a1
git commit -m "Merge master into website-ui: resolve conflicts
princerajpoot20 Apr 22, 2026
e5e3786
minor fix
princerajpoot20 Apr 22, 2026
de79d8c
Merge branch 'website-ui' of https://github.com/asyncapi/website into…
princerajpoot20 Apr 22, 2026
883dc1c
minor fix
princerajpoot20 Apr 22, 2026
c0982f9
Merge branch 'master' into website-ui
asyncapi-bot Apr 23, 2026
b1d8c7b
Merge branch 'master' into website-ui
asyncapi-bot Apr 23, 2026
e4324a8
Merge branch 'master' into website-ui
princerajpoot20 Apr 23, 2026
c80f7bb
Merge branch 'master' into website-ui
asyncapi-bot Apr 25, 2026
f30ef81
fix: fix Sonar, coderabbitai and visual issues (#5358)
aeworxet Apr 26, 2026
440ae3c
fixed sonar issues
princerajpoot20 Apr 26, 2026
2820a8d
fix more sonar issues
princerajpoot20 Apr 26, 2026
5badb2b
minor fix
princerajpoot20 Apr 26, 2026
d73034e
fix: address visual issues in Dark Theme (#5374)
aeworxet May 2, 2026
7c2813c
Merge branch 'master' into website-ui
princerajpoot20 May 2, 2026
29da255
fix: the rendering issue in the website-ui for the navbar (#5376)
Sourya07 May 5, 2026
6dc898b
Merge branch 'master' into website-ui
asyncapi-bot May 7, 2026
2af50b8
Merge branch 'master' into website-ui
princerajpoot20 May 7, 2026
714f545
fix: the lint issue and solved the ci pipeline (#5386)
Sourya07 May 10, 2026
80655ae
Merge branch 'master' into website-ui
princerajpoot20 May 10, 2026
7c21ddf
fix(ui): add dark theme visibility to Newsletter component text (#5399)
sammy200-ui May 12, 2026
06b0a05
add dark theme visibility to Roadmap modal text (#5398)
sammy200-ui May 12, 2026
c508ecd
Merge branch 'master' into website-ui
asyncapi-bot May 12, 2026
e39ca3c
fix(finance): dark mode theme for finance page (#5382)
sammy200-ui May 13, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,5 @@ config/tools-ignored.json
deno.lock
cypress/videos
cypress/screenshots
next-env.d.ts
*.tsbuildinfo
6 changes: 3 additions & 3 deletions components/Accordion/AccordionItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@ export default function AccordionItem({ itemIndex, title, content, isActive, set
}, [isActive]);

return (
<div className='my-2 flex size-full flex-col gap-1 border border-gray-200 bg-white px-2'>
<div className='my-2 flex size-full flex-col gap-1 border-none px-2'>
<button className='flex h-8 w-full items-center justify-between rounded-sm py-2' onClick={handleClick}>
<div className='font-body font-semibold text-gray-800 antialiased'>{title}</div>
<div className='font-body font-semibold text-gray-700 antialiased dark:text-white text-gray-700'>{title}</div>
<div>
{isActive ? (
<svg width='24' height='24' viewBox='0 0 24 24' fill='none' xmlns='http://www.w3.org/2000/svg'>
Expand Down Expand Up @@ -72,7 +72,7 @@ export default function AccordionItem({ itemIndex, title, content, isActive, set
>
<div
ref={contentRef}
className='rounded-sm border-t border-gray-200 py-2 font-body font-regular text-gray-700 antialiased'
className='rounded-sm border-none py-2 font-body font-regular text-gray-700 antialiased dark:text-white text-gray-700'
>
{content}
</div>
Expand Down
18 changes: 13 additions & 5 deletions components/Calendar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,15 @@ export default function Calendar({ className = '', size }: ICalendarProps) {
return (
<div
className={twMerge(
'overflow-hidden rounded-md border border-gray-200 bg-white p-4 h-full flex flex-col gap-2',
'overflow-hidden rounded-md border border-gray-200 bg-white dark:bg-dark-background dark:border-border p-4 h-full flex flex-col gap-2',
className
)}
>
<Heading level={HeadingLevel.h2} typeStyle={HeadingTypeStyle.mdSemibold}>
<Heading
level={HeadingLevel.h2}
typeStyle={HeadingTypeStyle.mdSemibold}
className='dark:text-dark-heading text-gray-900'
>
{t('calendar.title')}
</Heading>
<ul>
Expand All @@ -52,8 +56,10 @@ export default function Calendar({ className = '', size }: ICalendarProps) {
<span className='flex-1 self-center text-center'>{dayjs(event.date).format('D')}</span>
</div>
<div className='grow text-left sm:mt-0 sm:pl-6'>
<h2 className='title-font font-medium text-gray-900 hover:text-gray-500'>{event.title}</h2>
<p className='text-gray-600'>
<h2 className='title-font font-medium text-gray-900 dark:text-white hover:text-gray-500 dark:hover:text-gray-300'>
{event.title}
</h2>
<p className='text-gray-600 dark:text-gray-300'>
{dayjs(event.date).format('LLLL')} UTC
{dayjs(event.date).format('Z')}
</p>
Expand All @@ -63,7 +69,9 @@ export default function Calendar({ className = '', size }: ICalendarProps) {
))}
</ul>
<div className='h-full content-center'>
{!eventsExist && <div className='font-bold text-gray-700 lg:pb-8'>{t('calendar.noMeetingsMessage')}</div>}
{!eventsExist && (
<div className='font-bold text-gray-700 dark:text-gray-300 lg:pb-8'>{t('calendar.noMeetingsMessage')}</div>
)}
<div className='sm:pt-0 md:pt-2 lg:pb-8 lg:pt-0' data-testid='Calendar-button'>
<GoogleCalendarButton href={CALENDAR_URL} text={t('calendar.viewCalendarBtn')} />
</div>
Expand Down
35 changes: 21 additions & 14 deletions components/CaseStudyCard.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
import Link from 'next/link';
import React from 'react';

import type { ICaseStudies } from '@/types/post';
import type { ICaseStudies, ICaseStudy } from '@/types/post';
import { ParagraphTypeStyle } from '@/types/typography/Paragraph';

import Button from './buttons/Button';
import Paragraph from './typography/Paragraph';

interface ICaseStudyCardProps {
studies?: ICaseStudies;
}

/**
* @description A component that displays a list of case studies in a card format
* @description Displays case studies in a card grid layout
* @param {ICaseStudies} props.studies - The list of case studies to display
*/
export default function CaseStudyCard({ studies = [] }: ICaseStudyCardProps) {
Expand All @@ -19,21 +21,26 @@ export default function CaseStudyCard({ studies = [] }: ICaseStudyCardProps) {
}

return (
<div className='flex flex-wrap justify-center gap-3 pt-10 lg:gap-8 lg:text-center'>
{studies.map((study, index) => (
<a key={index} className='lg:w-[30%]' href={`casestudies/${study.id}`}>
<div
className='h-full min-h-[300px] max-w-sm overflow-hidden rounded-md border border-gray-200 bg-white p-4'
data-testid='CaseStudyCard-main'
>
<span className='mr-2'>
<img className='m-auto h-16' src={study.company.logo} alt={study.company.name} />
</span>
<Paragraph typeStyle={ParagraphTypeStyle.md} className='my-4'>
<div className='grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 lg:gap-8'>
{studies.map((study: ICaseStudy) => (
<Link key={study.id} href={`/casestudies/${study.id}`} className='group block h-full'>
<div className='h-full bg-white dark:bg-dark-background border border-gray-200 dark:border-gray-700 rounded-2xl p-6 transition-all duration-300 hover:shadow-xl hover:-translate-y-1'>
<div className='flex items-center justify-center h-20 mb-6'>
<img src={study.company.logo} alt={study.company.name} className='max-h-16 max-w-full object-contain' />
</div>

<Paragraph typeStyle={ParagraphTypeStyle.md} className='text-gray-600 dark:text-gray-400 mb-6 line-clamp-4'>
{study.company.description}
</Paragraph>

<div className='mt-auto'>
<Button
text='Read case study →'
className='w-full bg-primary-500 hover:bg-primary-600 text-white group-hover:bg-primary-600 transition-colors'
/>
</div>
Comment on lines +27 to +41
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

mt-auto will not push the button to the bottom without a flex container.

The mt-auto class on line 36 is intended to push the button to the bottom of the card, but it only works in a flex column layout. The parent div on line 27 lacks flex flex-col, so the button won't be anchored at the bottom when card heights vary.

🐛 Proposed fix to enable flex layout
-          <div className='h-full bg-white dark:bg-dark-background border border-gray-200 dark:border-gray-700 rounded-2xl p-6 transition-all duration-300 hover:shadow-xl hover:-translate-y-1'>
+          <div className='h-full flex flex-col bg-white dark:bg-dark-background border border-gray-200 dark:border-gray-700 rounded-2xl p-6 transition-all duration-300 hover:shadow-xl hover:-translate-y-1'>
📝 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
<div className='h-full bg-white dark:bg-dark-background border border-gray-200 dark:border-gray-700 rounded-2xl p-6 transition-all duration-300 hover:shadow-xl hover:-translate-y-1'>
<div className='flex items-center justify-center h-20 mb-6'>
<img src={study.company.logo} alt={study.company.name} className='max-h-16 max-w-full object-contain' />
</div>
<Paragraph typeStyle={ParagraphTypeStyle.md} className='text-gray-600 dark:text-gray-400 mb-6 line-clamp-4'>
{study.company.description}
</Paragraph>
<div className='mt-auto'>
<Button
text='Read case study →'
className='w-full bg-primary-500 hover:bg-primary-600 text-white group-hover:bg-primary-600 transition-colors'
/>
</div>
<div className='h-full flex flex-col bg-white dark:bg-dark-background border border-gray-200 dark:border-gray-700 rounded-2xl p-6 transition-all duration-300 hover:shadow-xl hover:-translate-y-1'>
<div className='flex items-center justify-center h-20 mb-6'>
<img src={study.company.logo} alt={study.company.name} className='max-h-16 max-w-full object-contain' />
</div>
<Paragraph typeStyle={ParagraphTypeStyle.md} className='text-gray-600 dark:text-gray-400 mb-6 line-clamp-4'>
{study.company.description}
</Paragraph>
<div className='mt-auto'>
<Button
text='Read case study →'
className='w-full bg-primary-500 hover:bg-primary-600 text-white group-hover:bg-primary-600 transition-colors'
/>
</div>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@components/CaseStudyCard.tsx` around lines 27 - 41, The container div that
wraps the card content in CaseStudyCard has mt-auto on the button wrapper but is
not a flex column, so the button won't be pushed to the bottom; update the root
card container (the div with classes 'h-full bg-white dark:bg-dark-background
border ... p-6') to use a flex column layout (add 'flex flex-col') so the child
div with 'mt-auto' will anchor the Button to the card bottom.

</div>
</a>
</Link>
Comment on lines +26 to +43
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Inspect Button to determine the rendered element(s).
fd -t f 'Button.tsx' components/buttons
fd -t f 'Button.tsx' components/buttons --exec cat {}

Repository: asyncapi/website

Length of output: 18240


Replace the Button with a styled non-interactive <span> to avoid invalid nested interactive elements.

The Button component is called without an href prop, so it renders as a <button> element nested inside the parent Next.js Link (which renders an <a>). Nested interactive elements break HTML semantics and keyboard/assistive technology navigation. The parent Link already provides the click target and navigation, so the Button should be a non-interactive styled element.

Suggested fix
<Link key={study.id} href={`/casestudies/${study.id}`} className='group block h-full'>
  <div className='h-full bg-white dark:bg-dark-background border border-gray-200 dark:border-gray-700 rounded-2xl p-6 transition-all duration-300 hover:shadow-xl hover:-translate-y-1'>
    <div className='flex items-center justify-center h-20 mb-6'>
      <img src={study.company.logo} alt={study.company.name} className='max-h-16 max-w-full object-contain' />
    </div>

    <Paragraph typeStyle={ParagraphTypeStyle.md} className='text-gray-600 dark:text-gray-400 mb-6 line-clamp-4'>
      {study.company.description}
    </Paragraph>

    <div className='mt-auto'>
      <span className='inline-block w-full bg-primary-500 hover:bg-primary-600 text-white group-hover:bg-primary-600 transition-colors rounded-md px-4 py-3 text-md font-semibold tracking-heading'>
        Read case study →
      </span>
    </div>
  </div>
</Link>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@components/CaseStudyCard.tsx` around lines 26 - 43, The Button inside the
Link creates invalid nested interactive elements; replace the interactive
<Button> usage in CaseStudyCard (the Button call rendering inside the Link
block) with a non-interactive styled element (e.g., a <span> or <div>) so the
parent Next.js Link remains the only clickable element; preserve the visual
styling and classes (w-full bg-primary-500 hover:bg-primary-600 text-white
group-hover:bg-primary-600 transition-colors and any rounded/padding/text
classes) and keep it inside the same container div that uses study.id and the
Link href `/casestudies/${study.id}` and ensure accessibility by not adding
button semantics or an href on the inner element.

))}
</div>
);
Expand Down
6 changes: 3 additions & 3 deletions components/CaseTOC.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ function TOCItem({ item, index, currSelected, closeMenu }: TOCItemProps) {
<nav className='relative block max-w-max'>
<a
className={twMerge(
'font-normal mb-1 flex items-center font-sans text-sm text-gray-900 antialiased transition duration-100 ease-in-out hover:underline',
'font-normal mb-1 flex items-center font-sans text-sm dark:text-white text-gray-900 antialiased transition duration-100 ease-in-out hover:underline',
active && 'font-bold text-primary-500'
)}
href={`#${item.slug}`}
Expand Down Expand Up @@ -168,8 +168,8 @@ export default function CaseTOC({ className, cssBreakingPoint = 'xl', toc }: Cas
open && 'mb-4'
} flex-1 text-primary-500 font-medium uppercase tracking-wide text-sm font-sans antialiased ${
cssBreakingPoint === 'xl'
? 'xl:mb-4 xl:text-xs xl:text-gray-900 xl:font-bold'
: 'lg:mb-4 lg:text-xs lg:text-gray-900 lg:font-bold'
? 'xl:mb-4 xl:text-xs xl:text-gray-900 dark:text-gray-300 xl:font-bold'
: 'lg:mb-4 lg:text-xs lg:text-gray-900 dark:text-gray-300 lg:font-bold'
}`
)}
>
Expand Down
86 changes: 86 additions & 0 deletions components/DarkModeToggle.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
'use client';

import { useEffect, useState } from 'react';

// SVG Icons as components
const SunIcon = ({ className = 'w-5 h-5' }) => (
<svg
className={className}
fill='none'
stroke='white'
strokeWidth='2'
viewBox='0 0 24 24'
xmlns='http://www.w3.org/2000/svg'
>
<circle cx='12' cy='12' r='5' />
<path d='M12 1v2M12 21v2M4.22 4.22l1.42 1.42M18.36 18.36l1.42 1.42M1 12h2M21 12h2M4.22 19.78l1.42-1.42M18.36 5.64l1.42-1.42' />
</svg>
);

const MoonIcon = ({ className = 'w-5 h-5' }) => (
<svg
className={`stroke-current text-opacity-85 text-zinc-600 ${className}`}
fill='none'
strokeWidth='2'
viewBox='0 0 24 24'
xmlns='http://www.w3.org/2000/svg'
>
<path d='M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z' />
</svg>
);

/**
* A modern toggle button component that switches between light and dark mode.
* Remembers the selected mode using localStorage with smooth animations.
*/
export default function DarkModeToggle() {
const [isDark, setIsDark] = useState(false);
const [mounted, setMounted] = useState(false);

useEffect(() => {
setMounted(true);
// Load preference on mount
const storedTheme = localStorage.getItem('theme');
const systemPrefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches; // NOSONAR

const shouldUseDark = storedTheme === 'dark' || (!storedTheme && systemPrefersDark);

document.documentElement.classList.toggle('dark', shouldUseDark);
setIsDark(shouldUseDark);
}, []);

const toggleDarkMode = () => {
const newTheme = !isDark;

document.documentElement.classList.toggle('dark', newTheme);
localStorage.setItem('theme', newTheme ? 'dark' : 'light');
setIsDark(newTheme);
};

// Prevent hydration mismatch
if (!mounted) {
return <div className='w-10 h-10 rounded-lg bg-gray-100 dark:bg-gray-800 animate-pulse' />;
}

return (
<button
onClick={toggleDarkMode}
className='relative p-2 mx-2 text-zinc-800 dark:text-zinc-800 hover:text-black dark:hover:text-white hover:bg-gray-100 dark:hover:bg-primary-500 rounded-lg transition-all duration-300 group'
aria-label={isDark ? 'Switch to light mode' : 'Switch to dark mode'}
>
{/* Icon container with smooth rotation */}
<div className='relative w-5 h-5 transition-transform duration-300 group-hover:scale-110'>
{isDark ? (
<SunIcon className='w-5 h-5 transition-all duration-300 rotate-0 group-hover:rotate-12' />
) : (
<MoonIcon className='w-5 h-5 transition-all duration-300 rotate-0 group-hover:-rotate-12' />
)}
</div>

{/* Tooltip */}
<div className='absolute -bottom-10 left-1/2 transform -translate-x-1/2 px-2 py-1 bg-gray-900 dark:bg-gray-100 text-white dark:text-gray-900 text-xs rounded opacity-0 group-hover:opacity-100 transition-opacity duration-300 pointer-events-none whitespace-nowrap'>
{isDark ? 'Light mode' : 'Dark mode'}
</div>
</button>
);
}
20 changes: 12 additions & 8 deletions components/Feedback.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -95,31 +95,35 @@ export default function Feedback({ className }: IFeedbackProps) {
}

return (
<div className={`flex flex-col rounded-md border border-gray-200 p-4 shadow-md ${className}`}>
<div
className={`flex flex-col rounded-md border dark:bg-dark-card dark:border-border border-gray-200 p-4 shadow-md ${className}`}
>
<div className='flex flex-row'>
<img src='/img/illustrations/icons/icon.svg' className='my-auto sm:size-14 lg:w-16' alt='' aria-hidden='true' />
<img src='/img/illustrations/icons/icon.svg' className='my-auto sm:size-14 lg:w-14' alt='' aria-hidden='true' />
<div className='ml-4 flex flex-col'>
<div className='text-xl'>Was this helpful?</div>
<div className='text-sm text-gray-500'>Help us improve the docs by adding your contribution.</div>
<div className='text-xl dark:text-dark-heading'>Was this helpful?</div>
<div className='text-sm dark:text-dark-text text-gray-500'>
Help us improve the docs by adding your contribution.
</div>
</div>
</div>
<form onSubmit={handleSubmit}>
<div className='my-4 flex flex-col'>
<textarea
className='inline-block h-20 w-full rounded-md border bg-gray-50 px-2 py-1 align-top text-sm text-gray-700 focus:border-0'
className='inline-block h-20 w-full rounded-md border dark:border-border dark:bg-dark-footer bg-gray-50 px-2 py-1 align-top text-sm text-gray-700 focus:border-0'
placeholder='Write your suggestions here'
onChange={(e) => setFeedback(e.target.value)}
required
/>
<div className='mt-4 block text-sm lg:flex lg:flex-row'>
<button
className='w-full rounded bg-primary-500 py-2 text-white shadow-md transition-all duration-500 ease-in-out hover:shadow-lg lg:w-6/12'
className='w-full rounded bg-primary-500 dark:border border-primary-500 dark:hover:bg-transparent py-2 text-white shadow-md transition-all duration-300 ease-in-out hover:shadow-lg lg:w-6/12'
type='submit'
>
Submit feedback
</button>
<div className='my-2 w-full text-center font-medium lg:my-auto lg:w-1/12'>OR</div>
<GitHubIssue />
<div className='my-2 w-full text-center dark:text-dark-text font-medium lg:my-auto lg:w-1/12'>OR</div>
<GitHubIssue className='bg-secondary-500 dark:border dark:border-secondary-500 dark:hover:bg-transparent' />
</div>
</div>
</form>
Expand Down
6 changes: 3 additions & 3 deletions components/FinancialSummary/AsyncAPISummary.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export default function AsyncAPISummary() {
<Heading level={HeadingLevel.h2} className='m-3 text-center text-5xl'>
AsyncAPI Financial Summary
</Heading>
<Paragraph typeStyle={ParagraphTypeStyle.md} className='my-1 max-w-4xl text-darkGunMetal'>
<Paragraph typeStyle={ParagraphTypeStyle.md} className='my-1 max-w-4xl text-darkGunMetal dark:text-dark-text'>
To help improve the current state of Event-Driven Architectures and their tooling, you can show your support
for the AsyncAPI Initiative by making a financial contribution. We offer three donation options:{' '}
<strong>Open Collective, GitHub Sponsors, and Linux Foundation Crowdfunding</strong>. Our expenses are
Expand All @@ -39,7 +39,7 @@ export default function AsyncAPISummary() {
Ways to Support Us?
</Heading>
</div>
<div className='max-width my-4 text-center text-base text-darkGunMetal'>
<div className='max-width my-4 text-center text-base text-darkGunMetal dark:text-dark-text'>
<Paragraph typeStyle={ParagraphTypeStyle.sm} className='my-4'>
The easiest way to support AsyncAPI is by becoming a financial sponsor. While{' '}
<br className='hidden lg:inline-block' />
Expand Down Expand Up @@ -69,7 +69,7 @@ export default function AsyncAPISummary() {
</a>
<a href='https://github.com/sponsors/asyncapi' target='_blank'>
<img
className='mx-4 inline size-10 transition-transform hover:scale-110 active:scale-90'
className='mx-4 inline size-10 transition-transform hover:scale-110 active:scale-90 dark:invert'
src='/img/logos/github-black.svg'
alt='Github'
/>
Expand Down
Loading
Loading