-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Error 429 - Too many requests #59
Comments
@BigAB, I updated the dependencies (mainly Svelte 3 to Svelte 4), which may have caused the issue. I had a quick look and it seems that there's an infinite loop in the |
I got things working with a lot of changes, but mostly in clerk.ts. I've included other files for reference so folks aren't guessing. My 'lil buddy ChatGPT helped by adding clarifying console log dumps etc. to get me to this point. The main issue is that the version you guys have creates multiple instances of the clerk module. This (hopefully) ensures that only one instance is used. clerk.ts import { writable, type Writable } from 'svelte/store';
import Clerk from '@clerk/clerk-js';
import type ClerkInstance from '@clerk/clerk-js';
import { PUBLIC_CLERK_PUBLISHABLE_KEY } from '$env/static/public';
// Create a writable store for Clerk
export const clerk: Writable<ClerkInstance | null> = writable(null);
// Initialize Clerk once
let clerkInstance: ClerkInstance | null = null;
export async function initializeClerk(): Promise<void> {
if (!clerkInstance && typeof window !== 'undefined') {
clerkInstance = new Clerk(PUBLIC_CLERK_PUBLISHABLE_KEY);
await clerkInstance
.load({
afterSignInUrl: '/',
afterSignUpUrl: '/',
signInUrl: '/sign-in',
signUpUrl: '/sign-up'
})
.catch((error: Error) => {
console.error('Failed to load Clerk:', error);
});
clerk.set(clerkInstance);
}
}
clerk.subscribe((clerkInstance) => {
// I'm setting window.Clerk so that I can access Clerk from my e2e tests to sign in programmatically without the UI
if (clerkInstance) window.Clerk = clerkInstance;
});
// This ensures that Clerk is initialized as soon as this module is imported.
initializeClerk(); clerk-ui.ts import type Clerk from '@clerk/clerk-js';
interface ClerkUIConfig {
clerk?: Clerk | null;
componentType: 'SignIn' | 'SignUp' | 'UserButton';
}
const COMPONENT_CONFIG: Record<ClerkUIConfig['componentType'], Record<string, unknown>> = {
SignIn: {},
SignUp: {},
UserButton: {
showName: false,
afterSignOutUrl: '/sign-in',
userProfileMode: 'modal'
}
};
export const clerkUI = (node: HTMLDivElement, { clerk, componentType }: ClerkUIConfig) => {
let currentComponentType = componentType;
console.log(`[ClerkUI] Initial component type: ${currentComponentType}`);
if (clerk) {
console.log(`[ClerkUI] Mounting initial ${currentComponentType}`);
clerk[`mount${currentComponentType}`](node, COMPONENT_CONFIG[currentComponentType]);
}
return {
update: ({ clerk: newClerk, componentType: newComponentType }: ClerkUIConfig) => {
console.log(`[ClerkUI] Update triggered. New component type: ${newComponentType}`);
if (currentComponentType !== newComponentType || clerk !== newClerk) {
console.log(`[ClerkUI] Unmounting previous ${currentComponentType}`);
clerk?.[`unmount${currentComponentType}`](node);
currentComponentType = newComponentType;
clerk = newClerk;
}
if (clerk) {
console.log(`[ClerkUI] Mounting updated ${currentComponentType}`);
clerk[`mount${currentComponentType}`](node, COMPONENT_CONFIG[currentComponentType]);
}
},
destroy: () => {
console.log(`[ClerkUI] Destroy called. Unmounting ${currentComponentType}`);
clerk?.[`unmount${currentComponentType}`](node);
}
};
}; hooks.server.ts import type { Handle } from '@sveltejs/kit';
import { verifySession } from '$lib/clerk-svelte/server/session';
export const handle: Handle = async ({ event, resolve }) => {
const sessionToken = event.cookies.get('__session');
if (sessionToken) {
console.log('[Server Hook] Found session token in cookies.');
try {
const session = await verifySession(sessionToken);
if (session) {
console.log('[Server Hook] Session verified successfully.');
event.locals.session = session;
} else {
console.warn('[Server Hook] Session verification returned no session.');
}
} catch (reason) {
console.warn('[Server Hook] Warning during session verification:', reason);
}
} else {
console.log('[Server Hook] No session token found in cookies.');
}
return resolve(event);
}; session.ts (server side) import { createClerkClient } from '@clerk/clerk-sdk-node';
import { CLERK_SECRET_KEY } from '$env/static/private';
import { json } from '@sveltejs/kit';
import type { RequestHandler, RequestEvent } from '@sveltejs/kit';
const clerk = createClerkClient({ secretKey: CLERK_SECRET_KEY });
export const users = clerk.users;
export const verifySession = async (sessionToken?: string) => {
if (sessionToken) {
try {
const claims = await clerk.verifyToken(sessionToken);
return {
userId: claims.sub,
claims
};
} catch (err) {
console.warn('ERROR', err);
}
}
};
export const requireSession = (handler: RequestHandler) => async (event: RequestEvent) => {
if (!event.locals.session) {
return json({ ok: false, error: 'Users Session not found' });
}
return handler(event);
}; +layout.server.ts import type { LayoutServerLoad } from './$types';
// get `locals.user` and pass it to the `page` store
export const load: LayoutServerLoad = async ({ locals }) => {
// Retrieve the session data from the locals object
const session = locals.session;
// If there's no session data, there's no need to pass anything to the client-side
if (!session) {
return { props: {} };
}
// Pass the session data to the client-side
return {
props: {
session
}
};
}; SignUp.svelte <script lang="ts">
import { clerkUI } from '$lib/clerk-svelte';
import { clerk } from '$lib/clerk-svelte/stores/clerk';
</script>
<div class="h-screen flex justify-center items-center">
<div
class="sign-up"
class:loading={!$clerk}
use:clerkUI={{ clerk: $clerk, componentType: 'SignUp' }}
/>
</div> routes/sign-up/+page.svelte <script lang="ts">
import { SignUp } from '$lib/clerk-svelte';
</script>
<SignUp /> example clerk store usage <script lang="ts">
import { UserButton } from '$lib/clerk-svelte';
import { clerk } from '$lib/clerk-svelte/stores/clerk';
</script>
{#if $clerk?.user}
<div class="m-2">
<UserButton />
</div>
{:else}
<a href="/sign-in" class="rounded bg-white text-black m-1 px-2 py-1">Sign in</a>
{/if} |
FYI this is now part of a package, here: https://github.com/markjaquith/clerk-sveltekit |
Thanks for working on this project!
When running this example project, I'm seeing an error code 429, "Too many requests" when I click the button to log in. I am using the code sent to my email as my sign-in strategy. I get 3 emails in my inbox before Clerk cuts off the requests (none of them work to sign in because it continues to send multiple sign-in requests). This happens both when I click the big button to sign up, as well as if I click "Didn't receive a code? Resend" buttons on the next page of the login form.
All of the actions are repeated more than once.
Any idea why this may be happening @BigAB? Thanks again for making such a comprehensive example!
The text was updated successfully, but these errors were encountered: