siingers
siingers5mo ago

sveltekit & authentication

I'm at a loss on how I'm meant to authenticate a user in a sveltekit app. Due to the docs being focused on react, I went with Clerk (which works), but not sure what I ought to be calling to authenticate with Convex now. Any help would be greatly appreciated.
76 Replies
siingers
siingersOP5mo ago
I think I understand a bit more now - convex-svelte uses the convexClient lib so I need to log the user in with Clerk, then setAuth on the convexClient, using clerk's getAuth to return the token in the Convex JWT template format https://discord.com/channels/1019350475847499849/1268719872171311125/1268835776591040522
joshpachner
joshpachner5mo ago
@siingers do you have an example of how that looks? Im in the same boat of svelte + convex + clerk
siingers
siingersOP5mo ago
I’m putting together what I’ve learned this weekend, I’ll message you a link when it’s ready!
joshpachner
joshpachner5mo ago
you're the best! ❤️‍🔥
siingers
siingersOP5mo ago
Not having a great time in all honesty. Would be great if the docs were fleshed out, not really sure what's the point in having other SDKs if authentication docs only care for react & next.
ballingt
ballingt5mo ago
@siingers have time to hop on a call sometime this afternoon or tomorrow? Message received that an SDK feels incomplete if it doesn't show how to hook up auth, when I wrote this indeed I didn't use external auth.
siingers
siingersOP5mo ago
this afternoon would be great! I'm in the UK & just finishing up work. Not sure what timezone you're in? Will be home from 6pm BST if that works for you, just give me a heads up
ballingt
ballingt5mo ago
Ah sorry, might need to be tomorrow; I'm in Portland recording one of these today https://www.youtube.com/watch?v=wPL13VR88iY
Learn With Jason
YouTube
Build an e-commerce site... with a twist — Web Dev Challenge S1E3
Sponsored by Algolia (https://lwj.dev/algolia) — What could you create if you had 30 minutes to plan and 4 hours to build? Sidney Buckner, Alex Trost, Shaundai Person, and Jason Lengstorf took on the Web Dev Challenge to find out. THE CHALLENGE Build an e-commerce site... with a twist. E-commerce makes the world go round, and we wanted to c...
ballingt
ballingt5mo ago
Sorry for the delay, this is more intensive than I imagined!
siingers
siingersOP5mo ago
No problem! Let me know if you find a minute tomorrow and good luck with the episode @ballingt I've got it working! I'll put a post together as promised to guide others once I've refactored as it's not the best implementation at the moment
ballingt
ballingt5mo ago
That's great! I could hop on a call if useful once I get through airport security in about 30 min, and regardless looking forward to updating the quickstart with an auth option.
siingers
siingersOP5mo ago
missed this message but appreciate the offer either way 👍 would like to get your opinion on my implementation though - all I had to do is: 1. have clerk-sveltekit configured 2. onMount, in the root +layout.svelte, attach a listener for the custom event that clerk-sveltekit fires whenever the clerk user object changes ("clerk-sveltekit:user") to the document, 3. pass the fetchToken function to the ConvexClient (assigned via useConvexClient() ), 4. and obviously have the convex/auth.config.ts configured & pushed Currently it runs everytime the window is observed, and isn't checking for the user state, but I'll put a check in place for that. Not 100% sure this needs to happen in layout.svelte, but I feel limited as the Clerk-Sveltekit package doesn't expose the store they use (there's a pull request to do this plus a lot more updating). Would like to know your thoughts Haven't tried implementing Convex Auth or anything else, i.e. Auth.js or Lucia
Shamim Hossain
Shamim Hossain4mo ago
Guys any luck! I've tried both Lucia and Auth.js for sveltekit authentication with convex backend but failed miserably 😦 I created a lucia-pocketbase adapter before for sveltekit projects which is working great. I followed the same pattern but I didn't find a way to pass a db client into the adapter itself. Maybe it's not possible I am not sure...
export class ConvexAdapter implements Adapter {
private db: DatabaseWriter;

constructor(db: DatabaseWriter) {
this.db = db;
}
export class ConvexAdapter implements Adapter {
private db: DatabaseWriter;

constructor(db: DatabaseWriter) {
this.db = db;
}
Here I have the db client which I am using to handle all the necessary users and sessions related operations but stuck to initialize it. Feels like convex is made for React & Next only. 😕
jamwt
jamwt4mo ago
it's not! we've invested time in things like svelte ( https://www.npmjs.com/package/convex-svelte ) because we do value it, and vue, and others. however the grim practicality is our team is still pretty small, and so it takes time to develop things! we just can't possibly ship every new feature at equivalent level in lock step at our current size, and yes -- react does get prioritized b/c the majority of our users are on it. it doesn't mean we don't want Svelte to be just as good eventually. but it's a resources thing
npm
convex-svelte
Convex is the typesafe backend-as-a-service with realtime updates, server functions, crons and scheduled jobs, file storage, vector search, and more.. Latest version: 0.0.9, last published: 2 months ago. Start using convex-svelte in your project by running npm i convex-svelte. There are no other projects in the npm r...
jamwt
jamwt4mo ago
sorry your experience hasn't been as good as you were hoping
siingers
siingersOP4mo ago
I got clerk working with it - see my message above. But for lucia I did find this: https://github.com/get-convex/convex-lucia-auth-demo Maybe that can get you on the right track
GitHub
GitHub - get-convex/convex-lucia-auth-demo: Demo showing authentica...
Demo showing authentication powered by Convex and Lucia - get-convex/convex-lucia-auth-demo
Shamim Hossain
Shamim Hossain4mo ago
The package you mentioned uses lucia v2 but I do need to work with lucia v3. Also, I tried to mimic that for sveltekit. The procedure seems a little bit complex for my understanding. Hi Jamie, my message wasn't meant for hurting anyone. Actually, I do know the svelte package you guys are working and I am using this one as well. Honestly, I spent like couple of days outside my office hours to integrate auth to one of my pet project. The frustration came from there. Neverthless, you guys are doing phenomenal job 👏
jamwt
jamwt4mo ago
no problem, no harm done at all! just making sure it's clear that we'd love to provide amazing and equal support for all of these frameworks if we had enough time and a bigger team, and we do aim to get there one day! in the mean time, we're open to PRs
siingers
siingersOP4mo ago
There's been an update for the clerk-sveltekit repo, it's currently still a PR but the author has made it available on npm. Upgrades to Clerk-Core 2 and adds refactors a bunch that makes more sense. https://github.com/markjaquith/clerk-sveltekit/pull/60#issuecomment-2313478868
GitHub
Upgrade to Core 2 by wobsoriano · Pull Request #60 · markjaquith/cl...
This PR upgrades the package to Clerk Core 2 with refreshed UI components and removes the @clerk/clerk-js dependency in favor of hot loading the clerk-js script which greatly reduces app bundle siz...
v
v4mo ago
I have a V3 demo
v
v4mo ago
Ignore the rest of the code, it's a bunch of testing on one repo but the auth works
Shamim Hossain
Shamim Hossain4mo ago
Thanks for the repo 🥰. After looking into the code, I just realized how close I was. I would try to implement that on the weekend. 🤞 Thanks for pointing that out. I would definitely watch it from now on.
v
v4mo ago
You definitely got this
siingers
siingersOP4mo ago
Will give this a try over the weekend!
v
v4mo ago
Shamim Hossain
Shamim Hossain4mo ago
@v I've tried to implement by following your setup on the lucia adapter but I am stuck on this error. I don't know have you faced this similar error before? I noticed that all the session expire_at values are converted to number but still it is yelling at the type mismatch issue. By the way, I've copy pasted your lucia.ts fiile and everything related to it.
Error: [CONVEX M(users:performPasswordLessLogin)] [Request ID: 2f2d6069d09ffe9b] Server Error
Uncaught Error: Date "2024-10-02T03:04:00.991Z" is not a supported Convex type (present at path .session.expiresAt in original object {"session":{"id":"rkkb4hmjksxdennpzisxraijgzglryhr45srrg7y","userId":"eroxmtfd3i6nj6ac","fresh":true,"expiresAt":"2024-10-02T03:04:00.991Z"},"cookie":"auth_session=rkkb4hmjksxdennpzisxraijgzglryhr45srrg7y; HttpOnly; Max-Age=2592000; Path=/; SameSite=Lax; Secure"}). To learn about Convex's supported types, see https://docs.convex.dev/using/types.
at convexToJsonInternal (../../node_modules/.pnpm/convex@1.14.3_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/convex/src/values/value.ts:339:6)
at convexToJsonInternal (../../node_modules/.pnpm/convex@1.14.3_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/convex/src/values/value.ts:350:15)
at convexToJsonInternal (../../node_modules/.pnpm/convex@1.14.3_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/convex/src/values/value.ts:350:15)
at convexToJson (../../node_modules/.pnpm/convex@1.14.3_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/convex/src/values/value.ts:417:0
Error: [CONVEX M(users:performPasswordLessLogin)] [Request ID: 2f2d6069d09ffe9b] Server Error
Uncaught Error: Date "2024-10-02T03:04:00.991Z" is not a supported Convex type (present at path .session.expiresAt in original object {"session":{"id":"rkkb4hmjksxdennpzisxraijgzglryhr45srrg7y","userId":"eroxmtfd3i6nj6ac","fresh":true,"expiresAt":"2024-10-02T03:04:00.991Z"},"cookie":"auth_session=rkkb4hmjksxdennpzisxraijgzglryhr45srrg7y; HttpOnly; Max-Age=2592000; Path=/; SameSite=Lax; Secure"}). To learn about Convex's supported types, see https://docs.convex.dev/using/types.
at convexToJsonInternal (../../node_modules/.pnpm/convex@1.14.3_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/convex/src/values/value.ts:339:6)
at convexToJsonInternal (../../node_modules/.pnpm/convex@1.14.3_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/convex/src/values/value.ts:350:15)
at convexToJsonInternal (../../node_modules/.pnpm/convex@1.14.3_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/convex/src/values/value.ts:350:15)
at convexToJson (../../node_modules/.pnpm/convex@1.14.3_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/convex/src/values/value.ts:417:0
marnec
marnec4mo ago
I see that this thread is marked as resolved but I really don't feel it is. I'm still at a loss on how I should authenticate when using svelte. I'd prefer to use convex-auth but there isn't a svelte version just react. The docs don't state that convex auth only work for react and that other frameworks should rely on clerk or something else. What's the official take on this?
v
v4mo ago
I know this issue One second Did you figure it out ? In your method you should return a convex serializable type they way i do stuff in that repo is just really weird xd but i wonder how you are going about the passwordless login just via a sessionid kinda thing i would use lucia if you just want oauth and password login @Shamim Hossain are you in sveltekit looks like react in the browser i will make a super simple demo with no bloat for svelte kit
ballingt
ballingt4mo ago
@marnec feel free to open another support thread! It was probably marked resolved once this original poster said they were set. Convex Auth is in beta right now, the only thing implemented is React and there's still plenty to do. In general Clerk is a great choice, that's what I'd recommend. There are some folks who would prefer not to use Clerk and they've been jumping on Convex Auth before it's fully ready / stable, which has been very helpful for testing it. This thread is about trying to use Clerk with Convex with Svelte, and there's known work to be done to better support Clerk (at minimum, docs about how to integrate!) If there's something else you want for Svelte, (feel free to open a thread here but also) please create an issue at https://github.com/get-convex/convex-svelte
v
v4mo ago
hey tom, i made this, i thinks its an okay start. https://github.com/vynxc/lucia-svelte-convex-demo i know this thread is closed but not sure where to put it. so ill just leave it here anyways
GitHub
GitHub - vynxc/lucia-svelte-convex-demo
Contribute to vynxc/lucia-svelte-convex-demo development by creating an account on GitHub.
v
v4mo ago
forgot to use indexes lol
ballingt
ballingt4mo ago
Nice!
ballingt
ballingt4mo ago
Here's great, we should probably link to it from https://github.com/get-convex/convex-svelte too
GitHub
GitHub - get-convex/convex-svelte
Contribute to get-convex/convex-svelte development by creating an account on GitHub.
v
v4mo ago
Feel free to do whatever you want with it, if you wanna fork it and make it better or whatever that's cool too
Shamim Hossain
Shamim Hossain4mo ago
I didn't get much time to figure it. But still some things I don't get it. For example, I am using sveltekit but got react specific error, all the dates are converted to appropriate types but still gettting that issue. I even converted the expire_at to string but still getting the same issue.
v
v4mo ago
Do you have a repo
Shamim Hossain
Shamim Hossain4mo ago
Here is the repo in case you are wondering https://github.com/shamscorner/tutpick I just want to send a email magic link that I am going to validate later.
GitHub
GitHub - shamscorner/tutpick: Tutpick is a platform where anyone ca...
Tutpick is a platform where anyone can teach/learn anyone. - shamscorner/tutpick
v
v4mo ago
Okay I can look maybe tonight What time zone are you
Shamim Hossain
Shamim Hossain4mo ago
I am using sveltekit. I don't know why the error is showing in react context.
v
v4mo ago
Yeah that's interesting
Shamim Hossain
Shamim Hossain4mo ago
Anything that works for you. But mostly GMT+6
v
v4mo ago
https://github.com/shamscorner/tutpick/blob/07898678c8e2ff4544b866fb7db6cb9905c0dbd2/src/convex/users.ts#L101 This is the issue Session object has a date in it I would look at the new repo I sent I just stringify the whole object lol Also my get session code was extremely horrible and ugly If you want I can make a pr But it's easy to fix https://github.com/vynxc/lucia-svelte-convex-demo/blob/93ddd31c58a8e0dc6b6c50f93b1772a69d689000/src/convex/users.ts#L55 @Shamim Hossain Also I do auth via cookie for ssr reasons So https://github.com/vynxc/lucia-svelte-convex-demo/blob/93ddd31c58a8e0dc6b6c50f93b1772a69d689000/src/hooks.server.ts#L11 Then in the main layout server I do https://github.com/vynxc/lucia-svelte-convex-demo/blob/93ddd31c58a8e0dc6b6c50f93b1772a69d689000/src/routes/%2Blayout.server.ts#L3 To login
const result = await convex.mutation(register ? api.users.register : api.users.login, {
username,
password
});
const session = JSON.parse(result) as Session;
document.cookie = `session=${session.id}; path=/; expires=${new Date(session.expiresAt).toUTCString()};`;
await invalidateAll();
const result = await convex.mutation(register ? api.users.register : api.users.login, {
username,
password
});
const session = JSON.parse(result) as Session;
document.cookie = `session=${session.id}; path=/; expires=${new Date(session.expiresAt).toUTCString()};`;
await invalidateAll();
Calling invalid will cause the hook to reload, causing the data returned from the layout.server.ts to update automatically
Shamim Hossain
Shamim Hossain4mo ago
@v Thanks for all the information 😊 I really appreciate it. I would look into the repo that you sent and would go forward from there. I would love to have a PR but if you are busy enough, I think I can take care. Btw, the repo hasn't finished yet. After successful login, I have to work on the hooks.server.ts and the layout way that you mentioned but of course mostly ssr.
v
v4mo ago
this repo thick boi 😂 @Shamim Hossain do you plan to use convex-ents
Shamim Hossain
Shamim Hossain4mo ago
I have one question here on your repo. Can we use singleton pattern instead of initiating lucia instance each time we make an auth related call?
export const getSession = query({
args: {
sessionId: v.string()
},
handler: async (ctx, args) => {
// getAuth is initiating each time
const auth = getAuth(ctx.db as DatabaseWriter);
const userSession = await auth.validateSession(args.sessionId);
return JSON.stringify(userSession);
}
});
export const getSession = query({
args: {
sessionId: v.string()
},
handler: async (ctx, args) => {
// getAuth is initiating each time
const auth = getAuth(ctx.db as DatabaseWriter);
const userSession = await auth.validateSession(args.sessionId);
return JSON.stringify(userSession);
}
});
v
v4mo ago
i dont think its possible
Shamim Hossain
Shamim Hossain4mo ago
It would be nice to have because the relations with ents are much easier.
v
v4mo ago
okay nice its prob just best to be behind a custom function but i could be wrong ofc
Shamim Hossain
Shamim Hossain4mo ago
I would research on here. That would be an improvement for sure.
v
v4mo ago
the offical repo does it this way too i think its okay just to put it as a custom function so you can do ctx.auth
Shamim Hossain
Shamim Hossain4mo ago
I think here maybe something like this:
export function getAuth(db: DatabaseWriter | DatabaseReader) {
// I think we can store the lucia in a global variable
// then check whether it is available
// if it is available, return that instance
// otherwise go forward means create a new lucia instance

const lucia = new Lucia(new ConvexAdapter(db as DatabaseWriter), {
getUserAttributes: (attributes) => {
return {
username: attributes.username
};
}
});
return lucia;
}
export function getAuth(db: DatabaseWriter | DatabaseReader) {
// I think we can store the lucia in a global variable
// then check whether it is available
// if it is available, return that instance
// otherwise go forward means create a new lucia instance

const lucia = new Lucia(new ConvexAdapter(db as DatabaseWriter), {
getUserAttributes: (attributes) => {
return {
username: attributes.username
};
}
});
return lucia;
}
v
v4mo ago
ill try it why not
Shamim Hossain
Shamim Hossain4mo ago
Awesome 🙂 I have office today. But after the office, I would try my way too. Great job btw! You managed to figure out quite a long way.
v
v4mo ago
i always figure things out but never polish them 😂 i aways write something nasty to look back on with disgust @Shamim Hossain i have made the changes but not sure if its working xd let me try ill get resend api key well it works mostly @Shamim Hossain should i commit this i see alot of the passwordless login stuff doesnt exist yet
v
v4mo ago
GitHub
GitHub - vynxc/tutpick: Tutpick is a platform where anyone can teac...
Tutpick is a platform where anyone can teach/learn anyone. - vynxc/tutpick
v
v4mo ago
check it out
Shamim Hossain
Shamim Hossain4mo ago
😄 me too sometimes. Thanks for this one. Let me mimic what you did and I would implement on my repo like that. But I have slight a different approach. I do want to handle the login in this route https://github.com/vynxc/tutpick/blob/feat/auth/src/routes/(onboarding)/auth/email-sign-in/%5Btoken%5D/%2Bserver.ts I would notify here whenver I am finished with this one.
v
v4mo ago
I know I probably shouldnt have changed it but I wanted to make sure it worked xd
Shamim Hossain
Shamim Hossain4mo ago
It's completely fine! I wasn't sure the flow either so who knows I would probably adopt your way to the implementation xd.
v
v4mo ago
let me know if you run into any issues @Shamim Hossain
Shamim Hossain
Shamim Hossain4mo ago
Hi @v , I have made some progress by following your implementation. I have pushed the code in feat/auth branch on my repo. Feel free to check that out. You can see the latest couple of commits for the changes that I have been made. However, I am getting a new error xd.
users:getSession
failure
152ms
Uncaught TypeError: this.db.delete is not a function
at deleteSession [as deleteSession] (../../src/convex/auth/lucia.ts:77:1)
at async validateSession [as validateSession] (../../node_modules/.pnpm/lucia@3.2.0/node_modules/lucia/dist/core.js:66:12)
at async getValidExistingSession (../../src/convex/auth/withAuth.ts:92:0)
at async handler (../../src/convex/auth/withAuth.ts:27:10)
users:getSession
failure
152ms
Uncaught TypeError: this.db.delete is not a function
at deleteSession [as deleteSession] (../../src/convex/auth/lucia.ts:77:1)
at async validateSession [as validateSession] (../../node_modules/.pnpm/lucia@3.2.0/node_modules/lucia/dist/core.js:66:12)
at async getValidExistingSession (../../src/convex/auth/withAuth.ts:92:0)
at async handler (../../src/convex/auth/withAuth.ts:27:10)
I don't know if you have time for this or not. But to reproduce, follow the steps: - go to homepage & click login - send a login link to your email or you can find that on the terminal - open that link - You would go to dashboard (if not, just visit manually) - check out the error log on the convex logs Btw, I temporarily comment the delete token call. Just to test that flow multiple times. When that is fixed, I would uncomment.
v
v4mo ago
Oh that's an oversight on my part It's because the DatabaseReader can't make mutations If you put whatever in a mutation it will fix it but that's not right Just gotta make the getValidExistingSession function read only Do you should be able to use getSession in that method instead of auth.validateSession(sessionId) I can test but it's 6am and I haven't slept xd
Shamim Hossain
Shamim Hossain4mo ago
Sure would try your suggested way. Please have some sleep 😊 I've managed to complete the authentication flow 🎉 Feel free to look at the last commit on the feat/auth branch. Now my next tasks are: - add error handling on the send login link server mutation - handle error page, example login link expired one - add session attributes - finish google auth - add 2fa - add user role - add team & user invitations - add authorizations. Want to make a scalable, production ready starter template in the future. 🤞
jamwt
jamwt4mo ago
nice! @Shamim Hossain make sure to let folks know in #sveltekit
v
v4mo ago
Gg to eZ
Shamim Hossain
Shamim Hossain4mo ago
Sure, would do that.
Tinapple
Tinapple4mo ago
Hi all, I read this thread looking for a svelte 5 way of using convex auth. I’m so impressed with convex-svelte, which I believe uses svelte 5 features. It is so amazing how svelte’s fine grained reactivity pairs up with convex reactivity. It’s so cool. I don’t quite grasp the conversation here, is this a svelte5 convex auth solution? I would love a convex auth svelte 5 demo. I’ve kind of jumped in a bit over my head with both svelte 5 and convex, and can only really understand by taking apart working demos. The convex-svelte demo is wonderful, thanks!
jamwt
jamwt4mo ago
yeah, it's cool to see the enthusiasm from Svelte folks! @ballingt did a lot of this work on our side. he's pretty knee deep in tanstack right now, but there's an opportunity at some point I'm sure for us to double back and see what more we can improve on the Svelte side of the house
jamwt
jamwt4mo ago
I did not like Svelte <=4 (played around with it and convex awhile ago here https://github.com/jamwt/svelte-convex ) b/c the composability story was really poor compared to react (or Solid, vue, etc). but Tom reassures me all is beautifully resolved with Svelte 5. I haven't had a chance to check it out yet
GitHub
GitHub - jamwt/svelte-convex: Quick, rough example using Convex wit...
Quick, rough example using Convex with Svelte. Contribute to jamwt/svelte-convex development by creating an account on GitHub.
Tinapple
Tinapple4mo ago
Ooh I will check this out, thanks. I hear you about svelte 4, I liked it from a developer joy standpoint, but as I made more complex things, the reactivity became difficult to follow. I didn’t understand why until learning svelte 5, which does reactivity with signals, at run time. It’s crazy good, and a whole lot more understandable and consistent. I’m so excited for svelte 5. And paired with convex it’s an incredible way to build. Note, when I say svelte I should say sveltekit. Im not a pro with back end or databases, but with sveltekit and convex it’s almost easy to build real-time synched web apps, even for newcomers. When svelte 5 ships any minute, I’m betting on a flood of great tutorials that I hope will include convex.
v
v4mo ago
GitHub
GitHub - vynxc/lucia-svelte-convex-demo
Contribute to vynxc/lucia-svelte-convex-demo development by creating an account on GitHub.
Shamim Hossain
Shamim Hossain4mo ago
@v shared a minimal approach which is I think what you need. But if you need something a little bit more organized, perhaps you can look into this as well. Just keep in mind that this still in active development 🙂 https://github.com/shamscorner/tutpick/tree/feat/auth
GitHub
GitHub - shamscorner/tutpick at feat/auth
Tutpick is a platform where anyone can teach/learn anyone. - GitHub - shamscorner/tutpick at feat/auth
yanis
yanis4mo ago
hey! are you using convex auth + lucia in this one?
v
v4mo ago
hes using lucia
Shamim Hossain
Shamim Hossain4mo ago
Hi 👋 I am using lucia + custom auth. Convex auth is using authjs under the hood probably.

Did you find this page helpful?