#svelte

33 messages · Page 1 of 1 (latest)

crystal crater
dark groveBOT
#

Hi @crystal crater. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:

#

You don’t need to follow Better Auth’s generic “installation + pick a DB adapter” flow when you’re using the Convex + Better Auth SvelteKit integration.

For Convex, you should follow the Convex component docs instead of the generic Better Auth DB setup:

  1. Install the Convex + Better Auth packages (this replaces choosing a DB adapter in Better Auth’s own docs):

    npm install @convex-dev/better-auth @mmailaender/convex-better-auth-svelte
    npm install better-auth@1.4.9 --save-exact
    

    [SvelteKit install]

  2. Register the component and auth config in Convex:

    // src/convex/convex.config.ts
    import { defineApp } from "convex/server";
    import betterAuth from "@convex-dev/better-auth/convex.config";
    
    const app = defineApp();
    app.use(betterAuth);
    
    export default app;
    
    // src/convex/auth.config.ts
    import { getAuthConfigProvider } from "@convex-dev/better-auth/auth-config";
    import type { AuthConfig } from "convex/server";
    
    export default {
      providers: [getAuthConfigProvider()],
    } satisfies AuthConfig;
    

    [SvelteKit install]

  3. Create the Convex-backed Better Auth instance (this is your “database integration”):

    // src/convex/auth.ts
    import { createClient, type GenericCtx } from "@convex-dev/better-auth";
    import { convex } from "@convex-dev/better-auth/plugins";
    import { components } from "./_generated/api";
    import { type DataModel } from "./_generated/dataModel";
    import { query } from "./_generated/server";
    import { betterAuth } from "better-auth/minimal";
    import authConfig from "./auth.config";
    
    const siteUrl = process.env.SITE_URL!;
#

export const authComponent = createClient<DataModel>(components.betterAuth);

export const createAuth = (ctx: GenericCtx<DataModel>) => {
return betterAuth({
baseURL: siteUrl,
database: authComponent.adapter(ctx),
emailAndPassword: {
enabled: true,
requireEmailVerification: false,
},
plugins: [convex({ authConfig })],
});
};

export const getCurrentUser = query({
args: {},
handler: async (ctx) => {
return authComponent.getAuthUser(ctx);
},
});

[[SvelteKit install](<https://labs.convex.dev/better-auth/framework-guides/sveltekit#installation>)]

4. **Create the Svelte auth client and wire it into SvelteKit**:

```ts
// src/lib/auth-client.ts
import { createAuthClient } from 'better-auth/svelte';
import { convexClient } from "@convex-dev/better-auth/client/plugins";

export const authClient = createAuthClient({
  plugins: [convexClient()],
});

[SvelteKit install]

<!-- src/routes/+layout.svelte -->
<script lang="ts">
  import '../app.css';
  import favicon from '$lib/assets/favicon.svg';
  import { createSvelteAuthClient } from '@mmailaender/convex-better-auth-svelte/svelte';
  import { authClient } from '$lib/auth-client';

  createSvelteAuthClient({ authClient });

  let { children } = $props();
</script>

<svelte:head>
  <link rel="icon" href={favicon} />
</svelte:head>

{@render children?.()}

[Convex client provider]

So:

#
  • The generic Better Auth docs talk about integrating with “another DB” because they’re framework/DB-agnostic.
  • When using Convex, Convex is your DB, and the @convex-dev/better-auth component plus authComponent.adapter(ctx) is the DB integration you should use, instead of the generic DB adapters in the Better Auth site.

If you’d like, I can outline the full SvelteKit checklist (hooks, SSR auth state, authenticated queries) based on the Convex docs only.

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:

#

@crystal crater Kapa.ai is still learning and improving, please let me know how I did by reacting below.

crystal crater
#

@dark grove Following the installation page instructions, installed
bun add better-auth

added
secret key and base url to .env

created auth.ts in src/lib/ and added
import { betterAuth } from "better-auth";

export const auth = betterAuth({
//...
});

but i'm confused how to continue here

Configure Database

Better Auth requires a database to store user data. You can easily configure Better Auth to use SQLite, PostgreSQL, or MySQL, and more!

You can also configure Better Auth to work in a stateless mode if you don't configure a database. See Stateless Session Management for more information. Note that most plugins will require a database.
sqlite
postgres
mysql
auth.ts

import { betterAuth } from "better-auth";
import Database from "better-sqlite3";
export const auth = betterAuth({
database: new Database("./sqlite.db"),
})
Alternatively, if you prefer to use an ORM, you can use one of the built-in adapters.

drizzle
prisma
mongodb
auth.ts

import { betterAuth } from "better-auth";
import { drizzleAdapter } from "better-auth/adapters/drizzle";
import { db } from "@/db"; // your drizzle instance
export const auth = betterAuth({
database: drizzleAdapter(db, {
provider: "pg", // or "mysql", "sqlite"
}),
});
If your database is not listed above, check out our other supported databases for more information, or use one of the supported ORMs.
since i want to use convex

dark groveBOT
#

Let me check the knowledge base for you again. One moment! :books:

#

You can ignore the generic “configure database” section from the Better Auth docs when you’re using Convex.

With Convex, you don’t create auth.ts in src/lib and you don’t pass a SQLite/Drizzle adapter. Instead:

  1. Move your Better Auth setup into the Convex side and use the Convex adapter:

    // src/convex/auth.ts
    import { createClient, type GenericCtx } from "@convex-dev/better-auth";
    import { convex } from "@convex-dev/better-auth/plugins";
    import { components } from "./_generated/api";
    import { type DataModel } from "./_generated/dataModel";
    import { query } from "./_generated/server";
    import { betterAuth } from "better-auth/minimal";
    import authConfig from "./auth.config";
    
    const siteUrl = process.env.SITE_URL!;
    
    // Component client: gives you the Convex DB adapter
    export const authComponent = createClient<DataModel>(components.betterAuth);
    
    export const createAuth = (ctx: GenericCtx<DataModel>) => {
      return betterAuth({
        baseURL: siteUrl,
        database: authComponent.adapter(ctx), // ← Convex is your DB
        emailAndPassword: {
          enabled: true,
          requireEmailVerification: false,
        },
        plugins: [
          convex({ authConfig }), // Convex integration plugin
        ],
      });
    };
    
    // Optional helper to get current user
    export const getCurrentUser = query({
      args: {},
      handler: async (ctx) => {
        return authComponent.getAuthUser(ctx);
      },
    });
    

    [SvelteKit install]

    Here, authComponent.adapter(ctx) is the “database” Better Auth uses; you do not configure SQLite/Drizzle/etc.

  2. Make sure the Convex Better Auth component is registered and auth config exists:

#
   // src/convex/convex.config.ts
   import { defineApp } from "convex/server";
   import betterAuth from "@convex-dev/better-auth/convex.config";

   const app = defineApp();
   app.use(betterAuth);

   export default app;
// src/convex/auth.config.ts
import { getAuthConfigProvider } from "@convex-dev/better-auth/auth-config";
import type { AuthConfig } from "convex/server";

export default {
  providers: [getAuthConfigProvider()],
} satisfies AuthConfig;

[SvelteKit install]

  1. Create the Svelte auth client (this replaces your src/lib/auth.ts):

    // src/lib/auth-client.ts
    import { createAuthClient } from "better-auth/svelte";
    import { convexClient } from "@convex-dev/better-auth/client/plugins";
    
    export const authClient = createAuthClient({
      plugins: [convexClient()],
    });
    

    [SvelteKit install]

  2. Wire it into SvelteKit’s root layout:

    <!-- src/routes/+layout.svelte -->
    <script lang="ts">
      import "../app.css";
      import favicon from "$lib/assets/favicon.svg";
      import { createSvelteAuthClient } from "@mmailaender/convex-better-auth-svelte/svelte";
      import { authClient } from "$lib/auth-client";
    
      createSvelteAuthClient({ authClient });
    
      let { children } = $props();
    </script>
    
    <svelte:head>
      <link rel="icon" href={favicon} />
    </svelte:head>
    
    {@render children?.()}
    

    [Convex client provider]

#

So the key change: delete/stop using your src/lib/auth.ts Better Auth instance and instead define createAuth in src/convex/auth.ts using authComponent.adapter(ctx). That’s how you “configure the database” when using Convex.

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:

#

@crystal crater Kapa.ai is still learning and improving, please let me know how I did by reacting below.

crystal crater
dark groveBOT
#

Let me check the knowledge base for you again. One moment! :books:

#

You’re running into a real docs mismatch between “generic Better Auth + SvelteKit” and “Convex + Better Auth + SvelteKit”.

From the Convex side, the situation is:

  • Convex + Better Auth is shipped as a Convex Component that already provides a database adapter and schema. You don’t pick SQLite/Drizzle/etc.
  • The Convex docs explicitly say that the default install uses the component’s built‑in schema and DB integration, and that the Better Auth CLI / schema generation only applies to local installs, not the default component install. [Basic usage; Local install]

For SvelteKit specifically, the Convex guide has its own flow:

  • Install @convex-dev/better-auth and the Svelte helper.
  • Register the component in src/convex/convex.config.ts.
  • Add src/convex/auth.config.ts with getAuthConfigProvider().
  • Create src/convex/auth.ts using authComponent.adapter(ctx) as the database option. [SvelteKit install]

That authComponent.adapter(ctx) is the “database configuration” for Better Auth when you’re using Convex; you do not use the SQLite/Drizzle/Mongo examples from the generic installation page in that case. [Component client]

The knowledge sources you provided don’t explain why the Better Auth SvelteKit page still links to the generic “configure database” section, so I can’t say whether that’s an oversight or just written assuming a non‑Convex backend. I can only say, based on the Convex docs:

#
  • When using Convex + Better Auth, follow the Convex SvelteKit guide and treat Convex as the DB via authComponent.adapter(ctx).
  • The generic DB adapter instructions on better-auth.com are for projects that are not using Convex.

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:

#

@crystal crater Kapa.ai is still learning and improving, please let me know how I did by reacting below.

crystal crater
dark groveBOT
#

Let me check the knowledge base for you again. One moment! :books:

#

Yes — for Convex you should follow the Convex-specific Better Auth docs, not the generic SvelteKit “configure database” flow.

From the Convex side, the recommended path is:

  • Use the Convex + Better Auth component (@convex-dev/better-auth) and its adapter instead of configuring SQLite/Drizzle/etc. [SvelteKit install; Component client]
  • For SvelteKit specifically, follow the Convex SvelteKit guide, which shows:
    • registering the component in src/convex/convex.config.ts
    • adding src/convex/auth.config.ts
    • creating src/convex/auth.ts with database: authComponent.adapter(ctx)
    • creating the Svelte auth client and wiring it into +layout.svelte [SvelteKit guide]

The knowledge I have doesn’t include the exact content of <https://www.better-auth.com/docs/integrations/convex,> but everything in the Convex docs points to using that Convex integration (and the SvelteKit-specific page under labs.convex.dev) as your source of truth, instead of the generic Better Auth “configure database” section.

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:

#

@crystal crater Kapa.ai is still learning and improving, please let me know how I did by reacting below.

crystal crater
dark groveBOT
#

Let me check the knowledge base for you again. One moment! :books:

#

Follow the Convex + Better Auth SvelteKit guide on labs.convex.dev, not the generic Better Auth installation / DB config pages.

Specifically, use this as your source of truth:

That guide:

  • Installs @convex-dev/better-auth and @mmailaender/convex-better-auth-svelte.
  • Registers the Better Auth Convex component in src/convex/convex.config.ts.
  • Adds src/convex/auth.config.ts with getAuthConfigProvider().
  • Creates src/convex/auth.ts using authComponent.adapter(ctx) as the database (Convex is your DB). [SvelteKit install]

The generic Better Auth docs that talk about:

  • better-auth in src/lib/auth.ts, and
  • configuring database: new Database("./sqlite.db") or drizzleAdapter(db, …)

are for non‑Convex backends and should be ignored in a Convex project. The Convex component replaces that whole “configure database” step. [Basic usage]

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:

#

@crystal crater Kapa.ai is still learning and improving, please let me know how I did by reacting below.

crystal crater
#

@dark grove Ok I followed that tutorial from labs.convex.dev but after adding

import type { Handle } from "@sveltejs/kit";
import { createAuth } from "$convex/auth.js";
import { getToken } from "@mmailaender/convex-better-auth-svelte/sveltekit";

export const handle: Handle = async ({ event, resolve }) => {
event.locals.token = await getToken(createAuth, event.cookies);

return resolve(event);
};
inside hooks.server.ts, I get the error Cannot find module '$convex/auth.js' or its corresponding type declarations

dark groveBOT
#

Let me check the knowledge base for you again. One moment! :books:

#

$convex/auth.js is just an alias path used in the SvelteKit guide; in your project it must actually exist and be resolvable.

From the Convex + Better Auth SvelteKit docs, the file is created as:

// src/convex/auth.ts
import { createClient, type GenericCtx } from "@convex-dev/better-auth";
import { convex } from "@convex-dev/better-auth/plugins";
import { components } from "./_generated/api";
import { type DataModel } from "./_generated/dataModel";
import { query } from "./_generated/server";
import { betterAuth } from "better-auth/minimal";
import authConfig from "./auth.config";

const siteUrl = process.env.SITE_URL!;

export const authComponent = createClient<DataModel>(components.betterAuth);

export const createAuth = (ctx: GenericCtx<DataModel>) => {
  return betterAuth({
    baseURL: siteUrl,
    database: authComponent.adapter(ctx),
    emailAndPassword: {
      enabled: true,
      requireEmailVerification: false,
    },
    plugins: [convex({ authConfig })],
  });
};

export const getCurrentUser = query({
  args: {},
  handler: async (ctx) => {
    return authComponent.getAuthUser(ctx);
  },
});

[SvelteKit install]

And the SvelteKit hook uses:

// src/hooks.server.ts
import type { Handle } from "@sveltejs/kit";
import { createAuth } from "$convex/auth.js";
import { getToken } from "@mmailaender/convex-better-auth-svelte/sveltekit";

export const handle: Handle = async ({ event, resolve }) => {
  event.locals.token = await getToken(createAuth, event.cookies);
  return resolve(event);
};

[Set up token]

For $convex/auth.js to resolve:

#
  1. Your Convex functions must live under src/convex and convex.json must say:

    {
      "functions": "src/convex/"
    }
    

    [SvelteKit guide]

  2. Your Svelte config must define the $convex alias:

    // svelte.config.js
    import adapter from '@sveltejs/adapter-auto';
    import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';
    
    const config = {
      preprocess: vitePreprocess(),
      kit: {
        adapter: adapter(),
        alias: {
          $convex: './src/convex'
        }
      }
    };
    
    export default config;
    

    [SvelteKit guide]

  3. File name vs import: the guide imports $convex/auth.js, but your file is src/convex/auth.ts. With the alias above, Vite/TS will resolve that automatically; you don’t need to rename it, just ensure the file exists at src/convex/auth.ts.

If you already have src/convex/auth.ts and the alias, but still see the error, it means one of:

  • convex.json is not pointing to src/convex, or
  • the $convex alias is missing/misspelled in svelte.config.js, or
  • the file path is different (e.g. src/convex/auth/index.ts).

Verify those three and the import { createAuth } from "$convex/auth.js"; should start working.

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:

#

@crystal crater Kapa.ai is still learning and improving, please let me know how I did by reacting below.

crystal crater
dark groveBOT
#

Let me check the knowledge base for you again. One moment! :books: