Closed nlaurie closed 3 weeks ago
So you mean the issue only happens on a plain Vue app and it works as expected on Nuxt?
That's weird, let me try to replicate it and I'll let you know. If you could also provide a basic example so I can just play with it. I tried doing
const { isLoaded, isSignedIn } = useAuth()
watchEffect(() => {
console.log('isLoaded', isLoaded.value)
console.log('isSignedIn', isSignedIn.value)
})
and I get changes 🤔
Yea , Nuxt website was working. and our Vue App failed.
We have a pretty large and complex Vue App. I can try and recreate the issue, but it may be difficult to get all the same context.
I made a quickstart template here. Let me know if you can repro the issue using that! Thank you
Ran the quick start and tried to simulate my environment , could not simulate it successfully (everything worked as expected in the simple app) .
I tried running a fork of the vue-clerk project, trying to add console logging to figure out what is going on.
As you may see with the console logging, the plugin gets added and initialized. I put a console entry in the addOnLoaded and it fired , the user was successfully logged on and fired an emission with a proper clerk user_id .
However the authCtx.value in the injected value is reporting everything as undefined when I'm referring to the compostables.
Seems like the plugin is running inside another Vue application instance somehow ???
Weird the ctx (VueClerkInjectionKeyType) is uninitialized , which. it is false since the user was logged in and produced a clerk emission event and clerk_id
How are you logging useAuth? Can I see?
I tried logging the values of useAuth
in the playground/pages/index.client.vue
file and got this:
The Playground is working correctly.
This logging is in my application , using a local fork of vue-clerk. to validate additional logging. I'm logging this after the clerk authenticates the session cookie , and the values are all undefined. const { authCtx } = useClerkProvider();
I'll try my best to replicate that issue. Can't really figure out the issue, but if you want to contribute, it's most likely in this function.
We are happy to contribute to the project. We have a major launch coming up for our new software that heavy relies on Vue / Clerk / Vuetify etc.
We are using it in both of its forms , our website uses the nuxtjs variant, and our SPA app uses the pure client side version (which is not working).
I have narrowed it down to ,
clerk.addListener((payload) => { console.error('on-addListener', payload); for (const [key, value] of Object.entries(payload)) state[key as keyof typeof state] = value; });
this is not firing any events , which in turn does not fill the client state ...
That's awesome to hear!
I know that the playground is working but I still tried logging changes in the clerk.addListener
callback and got updates 🤔
I have also , determined in my environment the addListener call is going into the this.premountMethodCalls due to the clerkjs not being available (load timing? ) so on the hydrateClerkJS the cb() was being called but not being wired to the clerkjs. ( basically loosing the connection )
I tried , but I'm not fully versed on the arichetucture so not sure if this is correct, either way it did not restore the events.
for (const [key, cb] of this.premountMethodCalls) {
if (key === 'addListener') {
console.log('relay listener');
clerkjs.addListener(cb);
} else {
cb();
}
}
I think in the Sandbox the app loads so fast the event always makes its way directly to the clerkjs. but in my SPA we have over 5M of uncompressed scripts that are loading causing it to take a divergent path. ie. ending up in premount.
I'm happy to keep searching , but any ideas would be appreciated.
Nick
To be honest, the reason I went with loading the clerk-js CDN instead of installing the npm module is to reduce the app bundle and increase performance of the app. But my question is how do I provide the clerk instance to the app via plugin if I'm loading Clerk async?
The ff. snippet will not work
export const clerkPlugin: Plugin = {
async install(app, options: IsomorphicClerkOptions & { initialState?: InitialState }) {
await loadClerkJsScript()
const clerk = await global.Clerk.load(this.options)
app.provide('somekey', { clerk })
},
}
I tried to look on how they're doing it in React and saw this. I copy pasted it and made it work with Vue. I'm not fully aware yet of the whole architecture, just the high-level overview. This solution they use with React hot loads Clerk CDN but premounts the methods. Allowing vue-clerk to provide the instance of clerk directly. This won't be a problem if Vue supports async/await when registering a plugin.
Maybe we can tweak the IsomorphicClerk class to fix this issue
Fixed It
I like the lighter package load/build , it does add a fair bit of complexity, now we need to figure out the SPA caching as well since its externally loaded.
I sent you a pull request to validate the change.
Like I said were are highly dependent on Clerk for our launch and will definitely exercise the hell out of this project. We appreciate the project and are happy to contribute however we can on the project.
One request, not sure what formatter your using for the project , but we have prettier installed and it's clobbering the project formatting , would be good to either add prettier params for preferred formatting or configuration to disable prettier , so its easier for code contribution.
One request, not sure what formatter your using for the project , but we have prettier installed and it's clobbering the project formatting , would be good to either add prettier params for preferred formatting or configuration to disable prettier , so its easier for code contribution.
I see. I just finished reviewing your PR and left a tiny request. Ignore the format request, I can run that for now on my end if it's causing issues on your setup
I left a question here btw. You can ignore that and answer here, then I'm ready to merge that PR! Will publish a new version rq after that
When upgrading to latest all of my code watching these references is no longer seeing any changes in clerk.
In my pinia store I have a clerk.addListener((emission) => { log.debug(
emission | user: ${emission.user?.id}
); });and it is correctly firing an event when the cached login authenticates. but on the SignIn form
const { isLoaded, isSignedIn } = useAuth();
isLoaded remains false and isSignedIn is undefined. They never change.
The only difference in my code is the upgrade to 0.4.0 .
This is a plain Vue application.
I also upgraded my nuxtjs website with this version and it seems to be working as expected.
I also added clerk.addOnLoaded(()=> { log.debug(
addOnLoaded
); })and this is firing the callback as expected