1 GitHub star = 1 new component.

Star the repo
Blog & Content

Changelog Section

Release-notes timeline with version tags, dates and new/improved/fixed entries labelled by text and icon.

changelogreleasestimelineupdates
Live Preview

Changelog

New components, improvements and fixes, shipped every week.

  1. v0.5.1

    Official MCP Server & 1-Click AI Integrations

    • NewOfficial remote SSE MCP server (mcp.astrocomponents.dev) and local stdio mode.
    • New1-click CLI installer (`npx astro-component-kit mcp install <client>`) for Cursor, Claude, Codex, Lovable and universal MCP.
    • NewDedicated /mcp interactive landing page with client tabs and tools catalog.
    • New8 built-in AI tools with real-time discovery of 340+ components, templates, and design tokens.
  2. v0.4.1

    Multi-page templates & e-commerce suite

    • NewThree complete production templates: Nova Store, Forma Studio & The Lobby.
    • New17 e-commerce components with persistent cart, filters and checkout.
    • NewLight theme tokens with adaptive ink-rgb contrast and theme toggle.
  3. v0.4.0

    SVG charts & 24 new sections

    • New40 zero-dependency SVG charts with tooltips and table fallbacks.
    • NewWaitlist, terminal and dashboard hero sections.
    • ImprovedChart color tokens validated for color-vision deficiency.
  4. v0.3.1

    Localized SEO

    • ImprovedMeta titles and descriptions in English, Spanish and Russian.
    • FixedCode blocks no longer appear in search snippets.
  5. v0.3.0

    Notes & categories

    • NewBrowse-by-category section on the home page.
    • FixedCategory titles resolve correctly in every locale.

Usage

Copy and paste this code into your React component:

tsx
import { ChangelogSection } from 'react-component-kit-ui/sections';

<ChangelogSection releases={[
    { version: 'v1.0.0', date: '2026-11-01', title: 'Stable', changes: [{ type: 'new', text: 'First stable release.' }] },
  ]} />

Manual Installation

If you are not using the npm package, create a new file and paste the following code: src/components/sections/ChangelogSection.tsx + ChangelogSection.css:

ChangelogSection.tsx
'use client';

import './ChangelogSection.css';

interface Change { type: 'new' | 'improved' | 'fixed'; text: string }

interface Release { version: string; date: string; title: string; changes: Change[] }

/**
 * ChangelogSection โ€” Release notes timeline with version tags, dates and
 * categorised entries (new / improved / fixed), each labelled with text + icon.
 *
 * @param {string} title - Section heading.
 * @param {string} subtitle - Section description.
 * @param {Array<{version: string, date: string, title: string, changes: Array<{type: 'new'|'improved'|'fixed', text: string}>}>} releases - Releases, newest first.
 * @param {{label: string, href: string}} subscribe - Optional RSS/updates link.
 * @param {string} variant - Layout (timeline|cards|compact).
 * @param {string} size - Vertical rhythm (sm|md|lg).
 * @param {string} className - Extra CSS class.
 */
export interface ChangelogSectionProps {
  title?: string;
  subtitle?: string;
  releases?: Release[];
  subscribe?: { label: string; href: string };
  variant?: 'timeline' | 'cards' | 'compact';
  size?: 'sm' | 'md' | 'lg';
  className?: string;
}

export function ChangelogSection({
  title = 'Changelog',
  subtitle = 'New components, improvements and fixes, shipped every week.',
  releases = [
    { version: 'v0.5.1', date: '2026-11-04', title: 'Official MCP Server & 1-Click AI Integrations', changes: [
      { type: 'new', text: 'Official remote SSE MCP server (mcp.astrocomponents.dev) and local stdio mode.' },
      { type: 'new', text: '1-click CLI installer (`npx astro-component-kit mcp install <client>`) for Cursor, Claude, Codex, Lovable and universal MCP.' },
      { type: 'new', text: 'Dedicated /mcp interactive landing page with client tabs and tools catalog.' },
      { type: 'new', text: '8 built-in AI tools with real-time discovery of 340+ components, templates, and design tokens.' },
    ] },
    { version: 'v0.4.1', date: '2026-11-04', title: 'Multi-page templates & e-commerce suite', changes: [
      { type: 'new', text: 'Three complete production templates: Nova Store, Forma Studio & The Lobby.' },
      { type: 'new', text: '17 e-commerce components with persistent cart, filters and checkout.' },
      { type: 'new', text: 'Light theme tokens with adaptive ink-rgb contrast and theme toggle.' },
    ] },
    { version: 'v0.4.0', date: '2026-11-03', title: 'SVG charts & 24 new sections', changes: [
      { type: 'new', text: '40 zero-dependency SVG charts with tooltips and table fallbacks.' },
      { type: 'new', text: 'Waitlist, terminal and dashboard hero sections.' },
      { type: 'improved', text: 'Chart color tokens validated for color-vision deficiency.' },
    ] },
    { version: 'v0.3.1', date: '2026-10-27', title: 'Localized SEO', changes: [
      { type: 'improved', text: 'Meta titles and descriptions in English, Spanish and Russian.' },
      { type: 'fixed', text: 'Code blocks no longer appear in search snippets.' },
    ] },
    { version: 'v0.3.0', date: '2026-10-12', title: 'Notes & categories', changes: [
      { type: 'new', text: 'Browse-by-category section on the home page.' },
      { type: 'fixed', text: 'Category titles resolve correctly in every locale.' },
    ] },
  ],
  subscribe = { label: 'Subscribe via RSS', href: '#' },
  variant = 'timeline',
  size = 'md',
  className = '',
}: ChangelogSectionProps) {
  const id = `cls-${Math.random().toString(36).slice(2, 8)}`;
  const typeLabel = { new: 'New', improved: 'Improved', fixed: 'Fixed' };
  const typeIcon = {
    new: '<path d="M12 5v14M5 12h14"/>',
    improved: '<path d="M12 19V5M5 12l7-7 7 7"/>',
    fixed: '<path d="M20 6 9 17l-5-5"/>',
  };
  const fmtDate = (d: string) => new Date(`${d}T00:00:00Z`).toLocaleDateString('en-US', { month: 'long', day: 'numeric', year: 'numeric', timeZone: 'UTC' });
  return (
    <>
      <div className="cq-changelog-section-cq" data-rk-01cab4="">
      <section className={`cls cls--${variant} cls--${size} ${className}`} aria-labelledby={id} data-rk-01cab4="">
        <div className="cls__inner" data-rk-01cab4="">
          <header className="cls__head" data-rk-01cab4="">
            <div data-rk-01cab4="">
              <h2 id={id} className="cls__title" data-rk-01cab4="">{title}</h2>
              <p className="cls__subtitle" data-rk-01cab4="">{subtitle}</p>
            </div>
            {subscribe && (
              <a className="cls__subscribe" href={subscribe.href} data-rk-01cab4="">
                <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" aria-hidden="true" data-rk-01cab4=""><path d="M4 11a9 9 0 0 1 9 9M4 4a16 16 0 0 1 16 16" data-rk-01cab4="" /><circle cx="5" cy="19" r="1" fill="currentColor" data-rk-01cab4="" /></svg>
                {subscribe.label}
              </a>
            )}
          </header>
          <ol className="cls__list" data-rk-01cab4="">
            {releases.map((r, __i: number) => (
              <li key={__i} className="cls__release" data-rk-01cab4="">
                <div className="cls__when" data-rk-01cab4="">
                  <span className="cls__version" data-rk-01cab4="">{r.version}</span>
                  <time dateTime={r.date} data-rk-01cab4="">{fmtDate(r.date)}</time>
                </div>
                <article className="cls__body" data-rk-01cab4="">
                  <h3 className="cls__release-title" data-rk-01cab4="">{r.title}</h3>
                  <ul className="cls__changes" data-rk-01cab4="">
                    {r.changes.map((c, __i: number) => (
                      <li key={__i} data-rk-01cab4="">
                        <span className={`cls__type cls__type--${c.type}`} data-rk-01cab4="">
                          <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="3" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true" dangerouslySetInnerHTML={{ __html: typeIcon[c.type] }} data-rk-01cab4=""></svg>
                          {typeLabel[c.type]}
                        </span>
                        <span data-rk-01cab4="">{c.text}</span>
                      </li>
                    ))}
                  </ul>
                </article>
              </li>
            ))}
          </ol>
        </div>
      </section>
      </div>
    </>
  );
}

export default ChangelogSection;
ChangelogSection.css
/* ChangelogSection โ€” ported from astro-component-kit (sections/ChangelogSection.astro) */

.cq-changelog-section-cq:where([data-rk-01cab4]) { container-type: inline-size; }
.cls:where([data-rk-01cab4]) {
  --cls-py: 5.5rem;
  padding: var(--cls-py) var(--sp-6, 1.5rem);
  background: var(--c-bg, #050505);
}
.cls--sm:where([data-rk-01cab4]) { --cls-py: 3.5rem; }
.cls--lg:where([data-rk-01cab4]) { --cls-py: 7.5rem; }
.cls__inner:where([data-rk-01cab4]) { max-width: 920px; margin: 0 auto; }
.cls__head:where([data-rk-01cab4]) { display: flex; justify-content: space-between; align-items: flex-end; gap: 1rem; flex-wrap: wrap; margin-bottom: 3rem; }
.cls__title:where([data-rk-01cab4]) { margin: 0 0 0.5rem; font-size: clamp(1.9rem, 4vw, 2.75rem); font-weight: 800; letter-spacing: -0.03em; color: var(--c-text-1, #fff); }
.cls__subtitle:where([data-rk-01cab4]) { margin: 0; font-size: 1.0625rem; color: var(--c-text-2, #a3a3a3); }
.cls__subscribe:where([data-rk-01cab4]) { display: inline-flex; align-items: center; gap: 0.45rem; min-height: 44px; padding: 0 1rem; border-radius: var(--r-md, 12px); border: 1px solid rgb(var(--ink-rgb, 255 255 255) / 0.14); color: var(--c-text-1, #fff); font-size: 0.875rem; font-weight: 600; text-decoration: none; }
.cls__subscribe:where([data-rk-01cab4]) svg:where([data-rk-01cab4]) { color: #f59e0b; }
.cls__subscribe:hover:where([data-rk-01cab4]) { border-color: rgb(var(--ink-rgb, 255 255 255) / 0.3); color: var(--c-text-1, #fff); }
.cls__subscribe:focus-visible:where([data-rk-01cab4]) { outline: 2px solid var(--c-primary-light, #d4a017); outline-offset: 2px; }
.cls__list:where([data-rk-01cab4]) { list-style: none; margin: 0; padding: 0; display: grid; gap: 2.5rem; }
.cls__release:where([data-rk-01cab4]) { display: grid; grid-template-columns: 180px 1fr; gap: 2rem; position: relative; }
.cls--timeline:where([data-rk-01cab4]) .cls__release:where([data-rk-01cab4])::before { content: ''; position: absolute; left: 196px; top: 10px; bottom: -2.5rem; width: 1px; background: rgb(var(--ink-rgb, 255 255 255) / 0.08); }
.cls--timeline:where([data-rk-01cab4]) .cls__release:last-child:where([data-rk-01cab4])::before { bottom: 0; }
.cls--timeline:where([data-rk-01cab4]) .cls__body:where([data-rk-01cab4]) { position: relative; padding-left: 2rem; }
.cls--timeline:where([data-rk-01cab4]) .cls__body:where([data-rk-01cab4])::before { content: ''; position: absolute; left: -21px; top: 7px; width: 9px; height: 9px; border-radius: 50%; background: var(--c-primary-light, #d4a017); box-shadow: 0 0 0 4px var(--c-bg, #050505); }
.cls--cards:where([data-rk-01cab4]) .cls__body:where([data-rk-01cab4]) { padding: 1.5rem; border-radius: var(--r-lg, 18px); background: rgb(var(--ink-rgb, 255 255 255) / 0.025); border: 1px solid var(--c-border, rgb(var(--ink-rgb, 255 255 255) / 0.07)); }
.cls--compact:where([data-rk-01cab4]) .cls__list:where([data-rk-01cab4]) { gap: 1.5rem; }
.cls--compact:where([data-rk-01cab4]) .cls__release:where([data-rk-01cab4]) { grid-template-columns: 1fr; gap: 0.5rem; }
.cls--compact:where([data-rk-01cab4]) .cls__when:where([data-rk-01cab4]) { flex-direction: row; align-items: center; }
.cls__when:where([data-rk-01cab4]) { display: flex; flex-direction: column; gap: 0.4rem; align-items: flex-start; }
.cls__version:where([data-rk-01cab4]) { padding: 0.2rem 0.6rem; border-radius: 6px; background: rgb(var(--ink-rgb, 255 255 255) / 0.06); border: 1px solid rgb(var(--ink-rgb, 255 255 255) / 0.1); font-family: var(--font-mono, monospace); font-size: 0.8125rem; color: var(--c-text-1, #fff); }
.cls__when:where([data-rk-01cab4]) time:where([data-rk-01cab4]) { font-size: 0.8125rem; color: var(--c-text-2, #a3a3a3); }
.cls__release-title:where([data-rk-01cab4]) { margin: 0 0 1rem; font-size: 1.25rem; font-weight: 700; color: var(--c-text-1, #fff); letter-spacing: -0.015em; }
.cls__changes:where([data-rk-01cab4]) { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.75rem; }
.cls__changes:where([data-rk-01cab4]) li:where([data-rk-01cab4]) { display: flex; align-items: flex-start; gap: 0.75rem; font-size: 0.9375rem; line-height: 1.55; color: var(--c-text-2, #c4c4c4); }
.cls__type:where([data-rk-01cab4]) { display: inline-flex; align-items: center; gap: 0.3rem; flex-shrink: 0; min-width: 5.5rem; padding: 0.15rem 0.5rem; border-radius: 999px; font-size: 0.75rem; font-weight: 650; }
.cls__type--new:where([data-rk-01cab4]) { background: rgba(57, 135, 229, 0.14); color: #a9cdf7; }
.cls__type--improved:where([data-rk-01cab4]) { background: rgba(144, 133, 233, 0.16); color: #c9c3f5; }
.cls__type--fixed:where([data-rk-01cab4]) { background: rgba(52, 195, 143, 0.14); color: #7ee2b8; }
@container (max-width: 680px) {
  .cls__release:where([data-rk-01cab4]) { grid-template-columns: 1fr; gap: 0.75rem; }
  .cls--timeline:where([data-rk-01cab4]) .cls__release:where([data-rk-01cab4])::before { display: none; }
  .cls--timeline:where([data-rk-01cab4]) .cls__body:where([data-rk-01cab4]) { padding-left: 0; }
  .cls--timeline:where([data-rk-01cab4]) .cls__body:where([data-rk-01cab4])::before { display: none; }
  .cls__when:where([data-rk-01cab4]) { flex-direction: row; align-items: center; }
}