How in the world do I order these?
Unanswered
Indian pariah dog posted this in #help-forum
Indian pariah dogOP
I am currently trying to set up an app with Clerk (authentication) and Ably (WebSockets for realtime communication), but I can't figure out how to architect this where one piece doesn't break another. I can't get Next.js, Ably, and Clerk to all work together.
The Component Tree in the render looks like this:
The problem is that I want Clerk to wrap Ably, because I want to prevent the client from being able to get a token from Ably until they're authenticated. But they all render, and Ably is trying to get a token before Clerk has the user signed in, it sends the request, and then the request times out after 10 seconds.
So I tried to get user info, and prevent the client from being instantiated until
So, is some sort of way to delay the instantiating of
Any ideas here?
The Component Tree in the render looks like this:
<ClerkProvider>
<AblyProvider client={client}>
<Layout>
<Component {...pageProps} />
</Layout>
</AblyProvider>
</ClerkProvider>The problem is that I want Clerk to wrap Ably, because I want to prevent the client from being able to get a token from Ably until they're authenticated. But they all render, and Ably is trying to get a token before Clerk has the user signed in, it sends the request, and then the request times out after 10 seconds.
So I tried to get user info, and prevent the client from being instantiated until
useUser().isSignedIn === true. But then I realized that I can't get access to useUser() at all because it can't be used outside of ClerkProvider. Since we're already in _app.tsx, there's not really a way to go out a layer and wrap things.So, is some sort of way to delay the instantiating of
client for Ably until Clerk finishes? I can't move client farther down, because then we're in the territory of reloading components, and I don't want to open and close connections to Ably repeatedly.Any ideas here?
3 Replies
Indian pariah dogOP
This is what I had arrived at before I realized I was trying to call a context outside of its provider and none of this was going to work:
import '@/styles/globals.scss';
import type { AppProps } from 'next/app';
import * as Ably from 'ably';
import { AblyProvider } from 'ably/react';
import { useEffect } from 'react';
import { ClerkProvider, useUser } from '@clerk/nextjs';
import Layout from '@/components/layout/Layout';
let client;
export default function App({ Component, pageProps }: AppProps) {
const user = useUser();
const isSignedIn = user.isSignedIn;
useEffect(() => {
if (!isSignedIn) return;
client = new Ably.Realtime.Promise({
authUrl: 'http://localhost:3000/api/createTokenRequest',
});
const handleBeforeUnload = () => {
client.connection.close();
};
window.addEventListener('beforeunload', handleBeforeUnload);
return () => {
window.removeEventListener('beforeunload', handleBeforeUnload);
};
}, [isSignedIn]);
return (
<ClerkProvider
appearance={{
baseTheme: 'dark',
layout: {
socialButtonsPlacement: 'bottom',
},
variables: { colorPrimary: '#000000' },
elements: {
'cl-formButtonPrimary':
'bg-black border border-black border-solid hover:bg-white hover:text-black',
socialButtonsBlockButton:
'bg-white border-gray-200 hover:bg-transparent hover:border-black text-gray-600 hover:text-black',
socialButtonsBlockButtonText: 'font-semibold',
formButtonReset:
'bg-white border border-solid border-gray-200 hover:bg-transparent hover:border-black text-gray-500 hover:text-black',
membersPageInviteButton:
'bg-black border border-black border-solid hover:bg-white hover:text-black',
card: 'bg-[#fafafa]',
},
}}
{...pageProps}
>
<AblyProvider client={client}>
<Layout>
<Component {...pageProps} />
</Layout>
</AblyProvider>
</ClerkProvider>
);
}Sorry for the broken up pieces. I'm trying to work around character limits to ask this question.