Skip to content

Commit

Permalink
feat(clerk-js): Add nonce to theme provider (#4509)
Browse files Browse the repository at this point in the history
Co-authored-by: Jacek <[email protected]>
  • Loading branch information
jescalan and jacekradko authored Nov 22, 2024
1 parent 92a4859 commit 7c27b0c
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 22 deletions.
5 changes: 5 additions & 0 deletions .changeset/tricky-rings-divide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@clerk/clerk-js": minor
---

If a nonce is provided, it is now made available to Clerk's internal components. This allows the nonce to be passed in to style-src in CSPs and work correctly.
15 changes: 10 additions & 5 deletions packages/clerk-js/src/ui/lazyModules/providers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ const OptionsProvider = lazy(() => import('../contexts').then(m => ({ default: m
const AppearanceProvider = lazy(() => import('../customizables').then(m => ({ default: m.AppearanceProvider })));
const VirtualRouter = lazy(() => import('../router').then(m => ({ default: m.VirtualRouter })));
const InternalThemeProvider = lazy(() => import('../styledSystem').then(m => ({ default: m.InternalThemeProvider })));
const StyleCacheProvider = lazy(() =>
import('../styledSystem/StyleCacheProvider').then(m => ({ default: m.StyleCacheProvider })),
);
const Portal = lazy(() => import('./../portal').then(m => ({ default: m.Portal })));
const VirtualBodyRootPortal = lazy(() => import('./../portal').then(m => ({ default: m.VirtualBodyRootPortal })));
const FlowMetadataProvider = lazy(() => import('./../elements').then(m => ({ default: m.FlowMetadataProvider })));
Expand All @@ -26,11 +29,13 @@ type LazyProvidersProps = React.PropsWithChildren<{ clerk: any; environment: any

export const LazyProviders = (props: LazyProvidersProps) => {
return (
<CoreClerkContextWrapper clerk={props.clerk}>
<EnvironmentProvider value={props.environment}>
<OptionsProvider value={props.options}>{props.children}</OptionsProvider>
</EnvironmentProvider>
</CoreClerkContextWrapper>
<StyleCacheProvider nonce={props.options.nonce}>
<CoreClerkContextWrapper clerk={props.clerk}>
<EnvironmentProvider value={props.environment}>
<OptionsProvider value={props.options}>{props.children}</OptionsProvider>
</EnvironmentProvider>
</CoreClerkContextWrapper>
</StyleCacheProvider>
);
};

Expand Down
20 changes: 3 additions & 17 deletions packages/clerk-js/src/ui/styledSystem/InternalThemeProvider.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,9 @@
// eslint-disable-next-line no-restricted-imports
import createCache from '@emotion/cache';
// eslint-disable-next-line no-restricted-imports
import { CacheProvider, ThemeProvider } from '@emotion/react';
import { ThemeProvider } from '@emotion/react';
import React from 'react';

import { useAppearance } from '../customizables';
import type { InternalTheme } from './index';

const el = document.querySelector('style#cl-style-insertion-point');

const cache = createCache({
key: 'cl-internal',
prepend: !el,
insertionPoint: el ? (el as HTMLElement) : undefined,
});
import type { InternalTheme } from './types';

type InternalThemeProviderProps = React.PropsWithChildren<{
theme?: InternalTheme;
Expand All @@ -22,9 +12,5 @@ type InternalThemeProviderProps = React.PropsWithChildren<{
export const InternalThemeProvider = (props: InternalThemeProviderProps) => {
const { parsedInternalTheme } = useAppearance();

return (
<CacheProvider value={cache}>
<ThemeProvider theme={parsedInternalTheme}>{props.children}</ThemeProvider>
</CacheProvider>
);
return <ThemeProvider theme={parsedInternalTheme}>{props.children}</ThemeProvider>;
};
26 changes: 26 additions & 0 deletions packages/clerk-js/src/ui/styledSystem/StyleCacheProvider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// eslint-disable-next-line no-restricted-imports
import createCache from '@emotion/cache';
// eslint-disable-next-line no-restricted-imports
import { CacheProvider } from '@emotion/react';
import React, { useMemo } from 'react';

const el = document.querySelector('style#cl-style-insertion-point');

type StyleCacheProviderProps = React.PropsWithChildren<{
nonce?: string;
}>;

export const StyleCacheProvider = (props: StyleCacheProviderProps) => {
const cache = useMemo(
() =>
createCache({
key: 'cl-internal',
prepend: !el,
insertionPoint: el ? (el as HTMLElement) : undefined,
nonce: props.nonce,
}),
[props.nonce],
);

return <CacheProvider value={cache}>{props.children}</CacheProvider>;
};

0 comments on commit 7c27b0c

Please sign in to comment.