jason
jason
CCConvex Community
Created by jason on 3/27/2025 in #general
Have you had a chance to explore `Better Auth`
Didn't know that channel existed. thanks
169 replies
CCConvex Community
Created by jason on 3/27/2025 in #general
Have you had a chance to explore `Better Auth`
Hi @erquhart Just want to check on the status of Better Auth module for Convex, w/r/t the switch to cookie-less approach you mentioned and TanStack example. I see lots of progress https://github.com/erquhart/convex-better-auth/commits/main/ Appreciate any color you can share on its readiness and timing to help plan around it
169 replies
CCConvex Community
Created by jason on 3/27/2025 in #general
Have you had a chance to explore `Better Auth`
Any guidance on how to set up the provider for Tanstack? It's a bit more complicated than the Next or Vite examples. Stuck on error of Type 'QueryClient' is missing the following properties from type 'IConvexReactClient': setAuth, clearAuth
import { createRouter as createTanStackRouter } from "@tanstack/react-router";
import { QueryClient } from "@tanstack/react-query";
import { routerWithQueryClient } from "@tanstack/react-router-with-query";
import { ConvexQueryClient } from "@convex-dev/react-query";
import { ConvexProviderWithAuth } from "convex/react";
import { useBetterAuth } from "@erquhart/convex-better-auth/react";
import { authClient } from "~/lib/auth-client";
import { routeTree } from "./routeTree.gen";
import { NotFound } from "~/components/not-found";
import { Error as ErrorBoundary } from "~/components/error";

export function createRouter() {
const PUBLIC_CONVEX_URL = import.meta.env.PUBLIC_CONVEX_URL;
const convexQueryClient = new ConvexQueryClient(PUBLIC_CONVEX_URL);

const queryClient: QueryClient = new QueryClient({
defaultOptions: {
queries: {
queryKeyHashFn: convexQueryClient.hashFn(),
queryFn: convexQueryClient.queryFn(),
},
},
});
convexQueryClient.connect(queryClient);

const router = routerWithQueryClient(
createTanStackRouter({
routeTree,
defaultPreload: "intent",
context: { queryClient },
Wrap: ({ children }) => (
<ConvexProviderWithAuth client={queryClient} useAuth={useBetterAuth(authClient)}> // Error is here
{children}
</ConvexProviderWithAuth>
),
defaultNotFoundComponent: NotFound,
defaultErrorComponent: ErrorBoundary,
scrollRestoration: false,
}),
queryClient,
);

return router;
}

declare module "@tanstack/react-router" {
interface Register {
router: ReturnType<typeof createRouter>;
}
}
import { createRouter as createTanStackRouter } from "@tanstack/react-router";
import { QueryClient } from "@tanstack/react-query";
import { routerWithQueryClient } from "@tanstack/react-router-with-query";
import { ConvexQueryClient } from "@convex-dev/react-query";
import { ConvexProviderWithAuth } from "convex/react";
import { useBetterAuth } from "@erquhart/convex-better-auth/react";
import { authClient } from "~/lib/auth-client";
import { routeTree } from "./routeTree.gen";
import { NotFound } from "~/components/not-found";
import { Error as ErrorBoundary } from "~/components/error";

export function createRouter() {
const PUBLIC_CONVEX_URL = import.meta.env.PUBLIC_CONVEX_URL;
const convexQueryClient = new ConvexQueryClient(PUBLIC_CONVEX_URL);

const queryClient: QueryClient = new QueryClient({
defaultOptions: {
queries: {
queryKeyHashFn: convexQueryClient.hashFn(),
queryFn: convexQueryClient.queryFn(),
},
},
});
convexQueryClient.connect(queryClient);

const router = routerWithQueryClient(
createTanStackRouter({
routeTree,
defaultPreload: "intent",
context: { queryClient },
Wrap: ({ children }) => (
<ConvexProviderWithAuth client={queryClient} useAuth={useBetterAuth(authClient)}> // Error is here
{children}
</ConvexProviderWithAuth>
),
defaultNotFoundComponent: NotFound,
defaultErrorComponent: ErrorBoundary,
scrollRestoration: false,
}),
queryClient,
);

return router;
}

declare module "@tanstack/react-router" {
interface Register {
router: ReturnType<typeof createRouter>;
}
}
169 replies
CCConvex Community
Created by jason on 3/27/2025 in #general
Have you had a chance to explore `Better Auth`
RE cookies: I'm assuming a Convex custom domain would solve that. But this makes me curious...how does Convex Auth handle cookies, given a user's website domain differs from their *.convex.cloud backend? Does that use JWT or something instead? (I personally like Better Auth being cookie-based especially with their cookie caching feature. Just curious.)
169 replies
CCConvex Community
Created by jason on 3/27/2025 in #general
Have you had a chance to explore `Better Auth`
I can also create a repo from my current TanstackStart+Convex+BetterAuth project, that has working Email OTP and redact my private stuff, if you'd like to hack on it to create an example. Might help us both out
169 replies
CCConvex Community
Created by jason on 3/27/2025 in #general
Have you had a chance to explore `Better Auth`
Would this limit ability to alter the users table, like to add an active planId for a SaaS? Otherwise sounds cool
169 replies
CCConvex Community
Created by jason on 3/27/2025 in #general
Have you had a chance to explore `Better Auth`
- TanStack Start + BetterAuth + Convex. - Goal is Email OTP & Github OAuth. But for now, just Email OTP, b/c OAuth has runtime errors (already reported on the better-auth-kit repo). I have Email OTP working to sign in/out, just not the 3 aspects listed in my previous message. - An example of Convex+BetterAuth with any JS framework, that's full enough to cover protecting private routes and protecting convex mutations & queries, would be immensely helpful as a reference - Non-goal for MVP, but security critical for production: getting BetterAuth's rateLimiter working with its database adapter. BetterAuth uses memory as the default store for its rate limiter, which isn't effective for serverless hosts. (I updated BetterAuth's config to use database storage, but this table is not created automatically which I assume it should be, on Convex, if in use. I haven't tried to create the table manually yet b/c I'm focused on the 3 items in my previous message. But Email OTP will need rate limiting to be secure in production, so I'll spend some time on this later.)
169 replies
CCConvex Community
Created by jason on 3/27/2025 in #general
Have you had a chance to explore `Better Auth`
Update on my end: I have Better Auth's Email OTP plugin working, to create a user, create a session, and delete a session on logout. (Better Auth's OAuth still encounters runtime errors, so I'll just hide that option on my login page for now.) Remaining to sort out: 1.) protecting private routes--i.e. to redirect to /login if unauthenticated, 2.) writing a helper to require authentication for certain Convex mutations & queries, 3.) making user object available to all routes. Do y'all have more clarity now on if a deeper integration between Convex & Better Auth is required? Asking b/c if so, that'd help me know to just pause my attempts for now.
169 replies
CCConvex Community
Created by jason on 3/27/2025 in #general
Have you had a chance to explore `Better Auth`
Just noticed I have no better auth tables in Convex either. I might be messing this up, but I assume the tables are created after running npx convex dev --once as long as convex/betterAuth.ts exists.
169 replies
CCConvex Community
Created by jason on 3/27/2025 in #general
Have you had a chance to explore `Better Auth`
Update: I got past the first build error: 1. Ping pushed an update to address it, so use this version or newer "@better-auth-kit/convex": "^1.1.4", 2. And I also needed to update my convex/tsconfig.json from "moduleResolution": "Bundler", to "moduleResolution": "bundler",. I don't recall setting this, so a default might need to be updated in Convex's code generation b/c TypeScript indicates that only lowercase is valid. Progress! Now the runtime error listed as #2 in my previous post still occurs trying to use the Github OAuth method to sign in. So, that's the next hurdle.
169 replies
CCConvex Community
Created by jason on 3/27/2025 in #general
Have you had a chance to explore `Better Auth`
🙏 awesome
169 replies
CCConvex Community
Created by jason on 3/27/2025 in #general
Have you had a chance to explore `Better Auth`
1. First issue was getting it to build. I created an issue for @Ping 's repo for that: https://github.com/ping-maxwell/better-auth-kit/issues/5 Editing the built files in node_modules just to keep going with this, so they used .js extensions on imports, allowed the project to build without errors. 2. Now, getting a runtime error when trying to use better auth's authClient to sign in with Github OAuth, and it's like my Convex URL cannot be found anymore, but I've had Convex working on this project prior to better auth
Error importing route file: Error: Client created with undefined deployment address. If you used an environment variable, check that it's set.
at validateDeploymentUrl (file:///Users/me/proj/node_modules/convex/dist/esm/common/index.js:15:11
Error importing route file: Error: Client created with undefined deployment address. If you used an environment variable, check that it's set.
at validateDeploymentUrl (file:///Users/me/proj/node_modules/convex/dist/esm/common/index.js:15:11
169 replies
CCConvex Community
Created by jason on 3/13/2025 in #general
I installed Convex on 2 apps today: 1.)
Thanks. 1.) I understand, just sharing where, I as a new user, got a little confused with the instructions ambiguity about where to save the file b/c if instructions said in the SvelteKit project root that'd remove the ambiguity. 2.) Makes sense on the peer deps. Having designed DX focused stuff and noticing Convex seems to care a lot about it too, just noting the inconsistency I found. Inverting the suggestion and extract all client libs into their own deps with similar naming would achieve consistency too convex-svelte, convex-react, etc. Just my unsolicited 2c. I try to share feedback when learning a new product with fresh eyes. Works either way 👍
8 replies
CCConvex Community
Created by jason on 3/13/2025 in #general
I installed Convex on 2 apps today: 1.)
oh good to know!
8 replies
CCConvex Community
Created by jason on 3/13/2025 in #general
I installed Convex on 2 apps today: 1.)
1. Step 3 of the SvelteKit Quickstart does not say where to save the convex.json file--in src, in convex, my monorepo root, or the SvelteKit root? Mentioning "...in the SvelteKit project root" would clarify this. https://docs.convex.dev/database/writing-data 2. The React client lib is available via convex/react, but Svelte is available convex-svelte. Possible to just make it available at convex/svelte too? Less guessing and more of "that just makes sense". 2. Similarly, React has useQuery and useMutation--beautiful. But Svelte has:
import { useConvexClient, useQuery } from "convex-svelte";
const getTasks = useQuery(api.tasks.get, {});
const client = useConvexClient();
client.mutation(api.tasks.createTask, { text: "Hello, world!" });
import { useConvexClient, useQuery } from "convex-svelte";
const getTasks = useQuery(api.tasks.get, {});
const client = useConvexClient();
client.mutation(api.tasks.createTask, { text: "Hello, world!" });
If it were refactored to mirror convext/react's, it'd be more intuitive. 4. The example mutation in the convex-svelte README is broken b/c it's missing proper imports. I submitted an issue. https://github.com/get-convex/convex-svelte Thanks for including Svelte in the docs!
8 replies