diff --git a/.changeset/smooth-buttons-accept-one.md b/.changeset/smooth-buttons-accept-one.md
new file mode 100644
index 00000000000..6e986eed219
--- /dev/null
+++ b/.changeset/smooth-buttons-accept-one.md
@@ -0,0 +1,5 @@
+---
+'@clerk/react': patch
+---
+
+Allow unstyled button components to accept a single React element passed as an array.
diff --git a/packages/react/src/components/__tests__/SignInButton.test.tsx b/packages/react/src/components/__tests__/SignInButton.test.tsx
index 03523dd2d15..de3e0e30304 100644
--- a/packages/react/src/components/__tests__/SignInButton.test.tsx
+++ b/packages/react/src/components/__tests__/SignInButton.test.tsx
@@ -89,6 +89,30 @@ describe('', () => {
expect(mockRedirectToSignIn).toHaveBeenCalled();
});
+ it('accepts a single child passed as an array', async () => {
+ const handler = vi.fn();
+
+ render(
+
+ {[
+ ,
+ ]}
+ ,
+ );
+
+ const btn = screen.getByText('custom button');
+ await userEvent.click(btn);
+
+ expect(handler).toHaveBeenCalled();
+ expect(mockRedirectToSignIn).toHaveBeenCalled();
+ });
+
it('uses text passed as children', async () => {
render(text);
diff --git a/packages/react/src/utils/childrenUtils.tsx b/packages/react/src/utils/childrenUtils.tsx
index 0e231b2241c..73b26c8c4af 100644
--- a/packages/react/src/utils/childrenUtils.tsx
+++ b/packages/react/src/utils/childrenUtils.tsx
@@ -18,6 +18,12 @@ export const assertSingleChild =
try {
return React.Children.only(children);
} catch {
+ const childArray = React.Children.toArray(children);
+
+ if (childArray.length === 1 && React.isValidElement(childArray[0])) {
+ return childArray[0];
+ }
+
return errorThrower.throw(multipleChildrenInButtonComponent(name));
}
};