Skip to content
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
0c8e71f
feat(marketing): add changelog page
Kitenite Jan 27, 2026
841c66f
refactor(marketing): update changelog to Linear-style inline layout
Kitenite Jan 27, 2026
34cc47f
feat(marketing): add sticky timeline navigation to changelog
Kitenite Jan 27, 2026
9513728
fix(marketing): align timeline dots on the gridline
Kitenite Jan 27, 2026
677f99e
fix(marketing): fix sticky timeline with proper flexbox layout
Kitenite Jan 27, 2026
3726655
style(marketing): change timeline indicator to orange vertical line
Kitenite Jan 27, 2026
9c13dad
style(marketing): remove duplicate date from changelog entries
Kitenite Jan 27, 2026
e967ea5
style(marketing): align timeline date with entry title
Kitenite Jan 27, 2026
0a8c25d
style(marketing): increase timeline top offset for title alignment
Kitenite Jan 27, 2026
48348f0
Add PR urls
Kitenite Jan 27, 2026
59b0736
refactor(marketing): extract changelog PR link styling to custom MDX …
Kitenite Jan 27, 2026
c88de0b
feat(marketing): add PRBadge component and update all changelogs
Kitenite Jan 27, 2026
d185095
docs(marketing): update changelog content from PR release notes
Kitenite Jan 27, 2026
351843c
Add images
Kitenite Jan 28, 2026
dc5671e
refactor(marketing): rename changelog files to match content
Kitenite Jan 28, 2026
c03630d
feat(marketing): use docs image for terminal tab changelog, add inlin…
Kitenite Jan 28, 2026
45d0daf
feat(marketing): add ghostty image for Ghostty section
Kitenite Jan 28, 2026
97d549c
feat(marketing): use ghostty as featured image for terminal tab chang…
Kitenite Jan 28, 2026
76d2d3b
style(marketing): crop 10% from bottom of ghostty image
Kitenite Jan 28, 2026
5452833
style(marketing): allow featured images to display at full width and …
Kitenite Jan 28, 2026
48f72b8
fix(marketing): prevent horizontal scroll on changelog entry page
Kitenite Jan 28, 2026
b623f69
fix(marketing): add overflow-hidden to GridCross component
Kitenite Jan 28, 2026
55a8118
merge: resolve conflict keeping changelog and blog nav links
Kitenite Jan 28, 2026
7aae212
fix(marketing): fix lint issues and remove blog from header nav
Kitenite Jan 28, 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
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
title: Resizable sidebar, multiple terminal tabs, and port visibility
date: 2025-12-16
---

## VS Code-Style Resizable Sidebar

Replaced the old panel system with a VS Code-like resizable sidebar for better control over your layout. [#457](https://github.com/superset-sh/superset/pull/457)

## Multiple Terminal Tabs

Create multiple terminal tabs per workspace for parallel workflows. [#452](https://github.com/superset-sh/superset/pull/452)

## Port Visibility

See which ports are in use directly in the UI. [#462](https://github.com/superset-sh/superset/pull/462)

## Multi-line URL Links

Terminal now supports clicking URLs that span multiple lines. [#467](https://github.com/superset-sh/superset/pull/467)
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
title: SQLite database, Sentry tracking, and Features section
date: 2025-12-23
---

## SQLite Local Database

Replaced lowdb with SQLite for faster and more reliable local data storage. [#477](https://github.com/superset-sh/superset/pull/477)

## Sentry Error Tracking

Added Sentry integration for better error tracking and debugging. [#484](https://github.com/superset-sh/superset/pull/484)

## Features and FAQ Sections

New Features and FAQ sections on the marketing homepage. [#472](https://github.com/superset-sh/superset/pull/472)
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
title: Electric SQL sync, Linear integration, and required updates
date: 2025-12-30
---

## Electric SQL Sync

Real-time task synchronization across devices with Electric SQL integration. [#511](https://github.com/superset-sh/superset/pull/511)

## Linear Integration

Bidirectional sync with Linear for seamless task management between Superset and Linear. [#503](https://github.com/superset-sh/superset/pull/503)

## Required Updates

New mechanism to enforce critical app updates when needed. [#552](https://github.com/superset-sh/superset/pull/552)

## Confirm on Quit

Optional confirmation dialog before closing the app to prevent accidental data loss. [#524](https://github.com/superset-sh/superset/pull/524)
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
title: Sidebar overhaul, workspaces page, and Better Auth migration
date: 2026-01-06
---

## Sidebar Overhaul

Completely redesigned sidebar with improved navigation and workspace management. [#601](https://github.com/superset-sh/superset/pull/601)

## Workspaces Page

New dedicated page to view and manage all your workspaces. Easily close projects you're done with. [#599](https://github.com/superset-sh/superset/pull/599)

## Workspace Status Indicators

Three-color status indicators show you the state of each workspace at a glance. [#588](https://github.com/superset-sh/superset/pull/588)

## PR Status in Changes View

See your pull request status directly in the Changes view header. [#608](https://github.com/superset-sh/superset/pull/608)
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
title: Task list view, diff scrollbar highlights, and router refactor
date: 2026-01-13
---

## Task List View

New task list view for managing your work items directly in the app. [#717](https://github.com/superset-sh/superset/pull/717)

## Diff Highlights in Scrollbar

See diff changes at a glance with highlights shown directly in the scrollbar. [#725](https://github.com/superset-sh/superset/pull/725)

## Shell Environment Fix

Fixed shell environment resolution for macOS GUI apps - your PATH and environment variables now work correctly. [#720](https://github.com/superset-sh/superset/pull/720)

## Scroll to Bottom Button

New button in terminal to quickly jump to the bottom of output. [#700](https://github.com/superset-sh/superset/pull/700)
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
title: Expanded changes view, organization settings, and diff improvements
date: 2026-01-20
---

## Expanded Changes Sidebar

New expanded view for the changes sidebar gives you more room to review your modifications. [#858](https://github.com/superset-sh/superset/pull/858)

## Organization Settings

Redesigned organization settings with better navigation and a new settings search feature. [#820](https://github.com/superset-sh/superset/pull/820)

## Diff View Improvements

Toggle to hide unchanged regions in the diff viewer. Side-by-side diff view now has a polished UI. [#845](https://github.com/superset-sh/superset/pull/845)

## Middle-Click to Close Tabs

Middle-click on any tab to quickly close it. [#853](https://github.com/superset-sh/superset/pull/853)
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
title: Terminal tab arrangement, docs support, and Ghostty
date: 2026-01-27
---

## Terminal Tab Arrangement

Drag and drop to rearrange terminal tabs with new keyboard shortcuts for navigation. [#980](https://github.com/superset-sh/superset/pull/980)

## Docs and Blog Support

Open documentation directly within the app for quick reference while coding. [#974](https://github.com/superset-sh/superset/pull/974)

## Ghostty Terminal Support

Added Ghostty as a terminal backend option. [#950](https://github.com/superset-sh/superset/pull/950)
46 changes: 46 additions & 0 deletions apps/marketing/src/app/changelog.xml/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { COMPANY } from "@superset/shared/constants";
import { getChangelogEntries } from "@/lib/changelog";

export async function GET() {
const entries = getChangelogEntries();
const baseUrl = COMPANY.MARKETING_URL;

const escapeXml = (str: string) =>
str
.replace(/&/g, "&")
.replace(/</g, "&lt;")
.replace(/>/g, "&gt;")
.replace(/"/g, "&quot;")
.replace(/'/g, "&apos;");

const rss = `<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>Superset Changelog</title>
<link>${baseUrl}/changelog</link>
<description>The latest updates, improvements, and new features in Superset.</description>
<language>en-us</language>
<lastBuildDate>${new Date().toUTCString()}</lastBuildDate>
<atom:link href="${baseUrl}/changelog.xml" rel="self" type="application/rss+xml"/>
${entries
.map(
(entry) => `
<item>
<title>${escapeXml(entry.title)}</title>
<link>${baseUrl}/changelog/${entry.slug}</link>
<description>${escapeXml(entry.description || "")}</description>
<pubDate>${new Date(entry.date).toUTCString()}</pubDate>
<guid isPermaLink="true">${baseUrl}/changelog/${entry.slug}</guid>
</item>`,
)
.join("")}
</channel>
</rss>`;

return new Response(rss, {
headers: {
"Content-Type": "application/xml",
"Cache-Control": "public, max-age=3600, s-maxage=3600",
},
});
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
"use client";

import { ArrowLeft } from "lucide-react";
import Image from "next/image";
import Link from "next/link";
import type { ReactNode } from "react";
import { GridCross } from "@/app/blog/components/GridCross";
import {
type ChangelogEntry,
formatChangelogDate,
} from "@/lib/changelog-utils";

interface ChangelogEntryLayoutProps {
entry: ChangelogEntry;
children: ReactNode;
}

export function ChangelogEntryLayout({
entry,
children,
}: ChangelogEntryLayoutProps) {
const formattedDate = formatChangelogDate(entry.date);

return (
<article className="relative min-h-screen">
{/* Grid background with dashed lines */}
<div
className="absolute inset-0 pointer-events-none"
style={{
backgroundImage: `
linear-gradient(to right, transparent 0%, transparent calc(50% - 384px), rgba(255,255,255,0.06) calc(50% - 384px), rgba(255,255,255,0.06) calc(50% - 383px), transparent calc(50% - 383px), transparent calc(50% + 383px), rgba(255,255,255,0.06) calc(50% + 383px), rgba(255,255,255,0.06) calc(50% + 384px), transparent calc(50% + 384px))
`,
}}
/>

{/* Hero header */}
<header className="relative border-b border-border">
<div className="max-w-3xl mx-auto px-6 pt-16 pb-10 md:pt-20 md:pb-12">
{/* Grid crosses */}
<GridCross className="top-0 left-0" />
<GridCross className="top-0 right-0" />

<div className="text-center">
<time
dateTime={entry.date}
className="text-sm font-mono text-muted-foreground uppercase tracking-wider"
>
{formattedDate}
</time>

<h1 className="text-3xl md:text-4xl lg:text-5xl font-medium tracking-tight text-foreground mt-4 mb-4">
{entry.title}
</h1>

{entry.description && (
<p className="text-base md:text-lg text-muted-foreground max-w-2xl mx-auto">
{entry.description}
</p>
)}
</div>
</div>

{/* Bottom crosses */}
<div className="max-w-3xl mx-auto px-6 relative">
<GridCross className="bottom-0 left-0" />
<GridCross className="bottom-0 right-0" />
</div>
</header>

{/* Back link section */}
<div className="relative border-b border-border">
<div className="max-w-3xl mx-auto px-6 py-4">
<Link
href="/changelog"
className="inline-flex items-center gap-2 text-sm text-muted-foreground hover:text-foreground transition-colors"
>
<ArrowLeft className="h-4 w-4" />
Back to Changelog
</Link>
</div>
</div>

{/* Featured image */}
{entry.image && (
<div className="relative max-w-3xl mx-auto px-6 pt-12">
<div className="relative aspect-video overflow-hidden border border-border">
<Image
src={entry.image}
alt={entry.title}
fill
className="object-cover"
priority
/>
</div>
</div>
)}

{/* Content */}
<div className="relative max-w-3xl mx-auto px-6 py-12">
<div className="prose max-w-none">{children}</div>
</div>

{/* Footer */}
<footer className="relative border-t border-border">
<div className="max-w-3xl mx-auto px-6 relative">
<GridCross className="top-0 left-0" />
<GridCross className="top-0 right-0" />
</div>
<div className="max-w-3xl mx-auto px-6 py-10">
<Link
href="/changelog"
className="inline-flex items-center gap-2 text-sm text-muted-foreground hover:text-foreground transition-colors"
>
<ArrowLeft className="h-4 w-4" />
All updates
</Link>
</div>
</footer>
</article>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { ChangelogEntryLayout } from "./ChangelogEntryLayout";
79 changes: 79 additions & 0 deletions apps/marketing/src/app/changelog/[slug]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import { COMPANY } from "@superset/shared/constants";
import type { Metadata } from "next";
import { notFound } from "next/navigation";
import { MDXRemote } from "next-mdx-remote/rsc";
import { mdxComponents } from "@/app/blog/components/mdx-components";
import { ArticleJsonLd } from "@/components/JsonLd";
import { getAllChangelogSlugs, getChangelogEntry } from "@/lib/changelog";
import { ChangelogEntryLayout } from "./components/ChangelogEntryLayout";

interface PageProps {
params: Promise<{ slug: string }>;
}

export default async function ChangelogEntryPage({ params }: PageProps) {
const { slug } = await params;
const entry = getChangelogEntry(slug);

if (!entry) {
notFound();
}

const url = `${COMPANY.MARKETING_URL}/changelog/${slug}`;

return (
<main>
<ArticleJsonLd
title={entry.title}
description={entry.description}
author="Superset Team"
publishedTime={new Date(entry.date).toISOString()}
url={url}
image={entry.image}
/>
<ChangelogEntryLayout entry={entry}>
<MDXRemote source={entry.content} components={mdxComponents} />
</ChangelogEntryLayout>
</main>
);
}

export async function generateStaticParams() {
return getAllChangelogSlugs().map((slug) => ({ slug }));
}

export async function generateMetadata({
params,
}: PageProps): Promise<Metadata> {
const { slug } = await params;
const entry = getChangelogEntry(slug);

if (!entry) {
return {};
}

const url = `${COMPANY.MARKETING_URL}/changelog/${slug}`;

return {
title: `${entry.title} | ${COMPANY.NAME} Changelog`,
description: entry.description,
alternates: {
canonical: url,
},
openGraph: {
title: entry.title,
description: entry.description,
type: "article",
url,
siteName: COMPANY.NAME,
publishedTime: entry.date,
...(entry.image && { images: [entry.image] }),
},
twitter: {
card: "summary_large_image",
title: entry.title,
description: entry.description,
...(entry.image && { images: [entry.image] }),
},
};
}
Loading
Loading