diff --git a/.changeset/gorgeous-birds-reflect.md b/.changeset/gorgeous-birds-reflect.md
new file mode 100644
index 0000000000..7d1df8315d
--- /dev/null
+++ b/.changeset/gorgeous-birds-reflect.md
@@ -0,0 +1,5 @@
+---
+"@uploadthing/react": patch
+---
+
+fix: prevent `NextSSRPlugin` script being inserted multiple times
diff --git a/.changeset/lazy-lions-reply.md b/.changeset/lazy-lions-reply.md
new file mode 100644
index 0000000000..246f1ca009
--- /dev/null
+++ b/.changeset/lazy-lions-reply.md
@@ -0,0 +1,5 @@
+---
+"@uploadthing/react": patch
+---
+
+feat: optional `nonce` prop for `NextSSRPlugin`
diff --git a/packages/react/src/next-ssr-plugin.tsx b/packages/react/src/next-ssr-plugin.tsx
index 71339240ef..09f8bd4913 100644
--- a/packages/react/src/next-ssr-plugin.tsx
+++ b/packages/react/src/next-ssr-plugin.tsx
@@ -1,6 +1,6 @@
"use client";
-import { useId } from "react";
+import { useId, useRef } from "react";
import { useServerInsertedHTML } from "next/navigation";
import type { EndpointMetadata } from "@uploadthing/shared";
@@ -9,20 +9,31 @@ declare const globalThis: {
__UPLOADTHING?: EndpointMetadata;
};
-export function NextSSRPlugin(props: { routerConfig: EndpointMetadata }) {
+export function NextSSRPlugin(props: {
+ routerConfig: EndpointMetadata;
+ nonce?: string;
+}) {
const id = useId();
+ const isInserted = useRef(false);
// Set routerConfig on server globalThis
globalThis.__UPLOADTHING = props.routerConfig;
useServerInsertedHTML(() => {
+ if (isInserted.current) return;
+ isInserted.current = true;
+
const html = [
// Hydrate routerConfig on client globalThis
`globalThis.__UPLOADTHING = ${JSON.stringify(props.routerConfig)};`,
];
return (
-
+
);
});