Skip to content

Commit

Permalink
Add a button to parse from __next_f from script tags in @rsc-parse/…
Browse files Browse the repository at this point in the history
…embedded

Next.js stores the RSC payload in script tags. I've added a button to the panel in `@rsc-parse/embedded` to make #923 easier to debug.
  • Loading branch information
alvarlagerlof committed May 10, 2024
1 parent 2cd0dd4 commit 55421c4
Show file tree
Hide file tree
Showing 5 changed files with 97 additions and 3 deletions.
10 changes: 10 additions & 0 deletions .changeset/nine-cobras-fly.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
"@rsc-parser/embedded": patch
"@rsc-parser/core": patch
"@rsc-parser/embedded-example": patch
"@rsc-parser/chrome-extension": patch
"@rsc-parser/storybook": patch
"@rsc-parser/website": patch
---

Add a button to read Next.js payload script tags
14 changes: 14 additions & 0 deletions packages/core/src/components/ReadNextScriptTagsButton.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import type { Meta, StoryObj } from "@storybook/react";

import { ReadNextScriptTagsButton } from "./ReadNextScriptTagsButton";

const meta: Meta<typeof ReadNextScriptTagsButton> = {
component: ReadNextScriptTagsButton,
};

export default meta;
type Story = StoryObj<typeof ReadNextScriptTagsButton>;

export const example: Story = {
name: "example",
};
16 changes: 16 additions & 0 deletions packages/core/src/components/ReadNextScriptTagsButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import React from "react";

export function ReadNextScriptTagsButton({
onClickRead,
}: {
onClickRead: () => void;
}) {
return (
<button
className="rounded-md bg-slate-600 px-2 py-0.5 text-white dark:bg-slate-300 dark:text-black"
onClick={onClickRead}
>
Read Next.js script tag payload
</button>
);
}
2 changes: 2 additions & 0 deletions packages/core/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { Logo } from "./components/Logo";
import { RecordButton } from "./components/RecordButton";
import { DebugCopyMessagesButton } from "./components/DebugCopyMessagesButton";
import { ClearMessagesButton } from "./components/ClearMessagesButton";
import { ReadNextScriptTagsButton } from "./components/ReadNextScriptTagsButton";
import { PanelLayout } from "./components/PanelLayout";
import {
BottomPanel,
Expand All @@ -24,6 +25,7 @@ export {
RecordButton,
DebugCopyMessagesButton,
ClearMessagesButton,
ReadNextScriptTagsButton,
PanelLayout,
BottomPanel,
BottomPanelOpenButton,
Expand Down
58 changes: 55 additions & 3 deletions packages/embedded/RscDevtoolsPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
ClearMessagesButton,
PanelLayout,
fetchPatcher,
ReadNextScriptTagsButton,
} from "@rsc-parser/core";
import React, {
ReactNode,
Expand All @@ -28,8 +29,13 @@ import React, {
export function RscDevtoolsPanel() {
const [isOpen, setIsOpen] = useState(false);

const { isRecording, startRecording, messages, clearMessages } =
useRscMessages();
const {
isRecording,
startRecording,
messages,
clearMessages,
readNextScriptTags,
} = useRscMessages();

return (
<ApplyStylingOnClient>
Expand All @@ -53,6 +59,11 @@ export function RscDevtoolsPanel() {
{messages.length > 0 ? (
<ClearMessagesButton onClickClearMessages={clearMessages} />
) : null}
<ReadNextScriptTagsButton
onClickRead={() => {
readNextScriptTags();
}}
/>
</>
}
closeButton={
Expand Down Expand Up @@ -146,7 +157,48 @@ function useRscMessages() {
setMessages([]);
}, []);

return { isRecording, startRecording, messages, clearMessages };
const readNextScriptTags = useCallback(() => {
try {
// @ts-expect-error This is a hack
const payload = self.__next_f.map((f) => f?.[1]).join("");

console.log("TEST", payload);

const messages = [
{
type: "RSC_CHUNK",
tabId: 0,
data: {
fetchUrl: window.location.href,
fetchMethod: "GET",
fetchStartTime: 0,
chunkStartTime: 0,
chunkEndTime: 0,
chunkValue: Array.from(new TextEncoder().encode(payload)),
},
} satisfies RscChunkMessage,
];

setIsRecording(true);
startTransition(() => {
setMessages(() => messages);
});
} catch (error) {
console.error(
new Error("Error parsing Next.js payload", {
cause: error,
}),
);
}
}, []);

return {
isRecording,
startRecording,
messages,
clearMessages,
readNextScriptTags,
};
}

function arraysEqual(a: unknown[], b: unknown[]) {
Expand Down

0 comments on commit 55421c4

Please sign in to comment.