diff --git a/.changeset/fair-balloons-share.md b/.changeset/fair-balloons-share.md
new file mode 100644
index 00000000..f3f6a75c
--- /dev/null
+++ b/.changeset/fair-balloons-share.md
@@ -0,0 +1,5 @@
+---
+"streamdown": patch
+---
+
+Fix stale rendering when in-block markdown content changes during streaming updates.
diff --git a/packages/streamdown/__tests__/components-rerender.test.tsx b/packages/streamdown/__tests__/components-rerender.test.tsx
index c0ed0429..6bfbb1a1 100644
--- a/packages/streamdown/__tests__/components-rerender.test.tsx
+++ b/packages/streamdown/__tests__/components-rerender.test.tsx
@@ -422,6 +422,39 @@ describe("sameNodePosition edge cases", () => {
expect(container.querySelector("ol")).toBeTruthy();
});
+
+ it("should re-render when only offset changes", () => {
+ const nodeV1 = {
+ position: {
+ start: { line: 1, column: 1, offset: 0 },
+ end: { line: 2, column: 5, offset: 20 },
+ },
+ };
+ const nodeV2 = {
+ position: {
+ start: { line: 1, column: 1, offset: 0 },
+ end: { line: 2, column: 5, offset: 35 },
+ },
+ };
+
+ const { container, rerender } = render(
+
+
+ - item
+
+
+ );
+
+ rerender(
+
+
+ - item
+
+
+ );
+
+ expect(container.querySelector("ol")).toBeTruthy();
+ });
});
describe("MemoParagraph block code unwrapping with data-block", () => {
diff --git a/packages/streamdown/lib/components.tsx b/packages/streamdown/lib/components.tsx
index 2449ca3a..8f0c33ad 100644
--- a/packages/streamdown/lib/components.tsx
+++ b/packages/streamdown/lib/components.tsx
@@ -42,6 +42,7 @@ const LANGUAGE_REGEX = /language-([^\s]+)/;
interface MarkdownPoint {
column?: number;
line?: number;
+ offset?: number;
}
interface MarkdownPosition {
end?: MarkdownPoint;
@@ -74,8 +75,10 @@ function sameNodePosition(prev?: MarkdownNode, next?: MarkdownNode): boolean {
return (
prevStart?.line === nextStart?.line &&
prevStart?.column === nextStart?.column &&
+ prevStart?.offset === nextStart?.offset &&
prevEnd?.line === nextEnd?.line &&
- prevEnd?.column === nextEnd?.column
+ prevEnd?.column === nextEnd?.column &&
+ prevEnd?.offset === nextEnd?.offset
);
}