Skip to content
23 changes: 23 additions & 0 deletions docs/changelog.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
---
title: Documentation Changelog
sidebar_order: 100
description: Track recent updates to Sentry docs
---

import {DocsChangelog} from 'sentry-docs/components/changelog/docsChangelog';


## Recent Updates

<DocsChangelog />

## Alternative Views

- [Full Content Dashboard](https://sentry-content-dashboard.sentry.dev/) - View all Sentry content (blog, videos, docs, changelog)
- [RSS Feed](https://sentry-content-dashboard.sentry.dev/api/docs/feed) - Subscribe to doc updates in your RSS reader
- [JSON API](https://sentry-content-dashboard.sentry.dev/api/docs) - Programmatically access changelog data

<Alert level="info">
The changelog updates automatically throughout the day. Summaries are generated by AI to provide quick, user-friendly insights into each update from the [getsentry/sentry-docs](https://github.com/getsentry/sentry-docs) repository.
</Alert>

143 changes: 143 additions & 0 deletions src/components/changelog/docsChangelog.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
import React from 'react';

Check failure on line 1 in src/components/changelog/docsChangelog.tsx

View workflow job for this annotation

GitHub Actions / Lint

'default' import from 'react' is restricted. Prefer named React imports (React types DO NOT need imported!)

interface ChangelogEntry {
author: string;
description: string;
id: string;
publishedAt: string;
title: string;
url: string;
filesChanged?: {
added: string[];
modified: string[];
removed: string[];
};
}

async function getChangelogEntries(): Promise<ChangelogEntry[]> {
try {
const res = await fetch('https://sentry-content-dashboard.sentry.dev/api/docs', {
next: {revalidate: 3600}, // Cache for 1 hour
});

if (!res.ok) {
throw new Error('Failed to fetch changelog');
}

return res.json();
} catch (error) {
// Error fetching changelog - return empty array
return [];
}
}

export async function DocsChangelog() {
const entries = await getChangelogEntries();

if (entries.length === 0) {
return (
<div className="rounded-lg border border-yellow-200 bg-yellow-50 p-4 text-yellow-800">
<p className="font-semibold">No changelog entries available</p>
<p className="text-sm">Check back later for updates.</p>
</div>
);
}

return (
<div className="space-y-8">
{entries.map(entry => {
const date = new Date(entry.publishedAt);
const totalFiles =
(entry.filesChanged?.added?.length || 0) +
(entry.filesChanged?.modified?.length || 0) +
(entry.filesChanged?.removed?.length || 0);

return (
<article
key={entry.id}
className="border-b border-gray-200 pb-8 last:border-0"
>
<header className="mb-3">
<h3 className="mb-2 text-xl font-semibold">
<a
href={entry.url}
target="_blank"
rel="noopener noreferrer"
className="text-primary hover:underline"
Copy link
Member

Choose a reason for hiding this comment

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

Image

Looks like the hover:underline is not being applied since it's a heading. I do think there should be an underline. But this creates a separate issue: it looks like .prose class is being applied which has some default styling for content on other docs pages. Things like text color, etc. Maybe it's worth removing all tailwind classes and seeing which ones are needed to get it to the desired look (border bottom after sections, etc) and leave a lot of it to default to the same styling as the other pages?

>
{entry.title.replace('Docs Update: ', '')}
</a>
</h3>
<div className="flex flex-wrap items-center gap-3 text-sm text-gray-600">
<time dateTime={entry.publishedAt}>
{date.toLocaleDateString('en-US', {
year: 'numeric',
month: 'long',
day: 'numeric',
})}
</time>
<span>•</span>
<span>by {entry.author}</span>
{totalFiles > 0 && (
<React.Fragment>
<span>•</span>
<span>{totalFiles} file{totalFiles !== 1 ? 's' : ''} changed</span>
</React.Fragment>
)}
</div>
</header>

<p className="mb-4 text-gray-700">{entry.description}</p>

{entry.filesChanged && totalFiles > 0 && (
<details className="text-sm">
<summary className="cursor-pointer text-gray-600 hover:text-gray-800">
View changed files
</summary>
<div className="mt-2 space-y-2 rounded-md bg-gray-50 p-3">
{entry.filesChanged.added && entry.filesChanged.added.length > 0 && (
<div>
<span className="font-semibold text-green-700">Added:</span>
<ul className="ml-4 mt-1 list-inside list-disc">
{entry.filesChanged.added.map(file => (
<li key={file} className="text-gray-700">
{file}
</li>
))}
</ul>
</div>
)}
{entry.filesChanged.modified && entry.filesChanged.modified.length > 0 && (
<div>
<span className="font-semibold text-blue-700">Modified:</span>
<ul className="ml-4 mt-1 list-inside list-disc">
{entry.filesChanged.modified.map(file => (
<li key={file} className="text-gray-700">
{file}
</li>
))}
</ul>
</div>
)}
{entry.filesChanged.removed && entry.filesChanged.removed.length > 0 && (
<div>
<span className="font-semibold text-red-700">Removed:</span>
<ul className="ml-4 mt-1 list-inside list-disc">
{entry.filesChanged.removed.map(file => (
<li key={file} className="text-gray-700">
{file}
</li>
))}
Copy link

Choose a reason for hiding this comment

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

Bug: React Key Collisions in Changelog Lists

The DocsChangelog component uses key={file} for list items in the "added", "modified", and "removed" file lists. This can lead to React key collisions if the same filename appears in more than one category for a single changelog entry, potentially causing rendering issues.

Fix in Cursor Fix in Web

</ul>
</div>
)}
</div>
</details>
)}
</article>
);
})}
</div>
);
}

4 changes: 4 additions & 0 deletions src/components/sidebar/sidebarNavigation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ const productSidebarItems = [
title: 'Concepts & Reference',
root: 'concepts',
},
{
title: 'Documentation Changelog',
root: 'changelog',
},
];

export async function SidebarNavigation({path}: {path: string[]}) {
Expand Down
Loading