mirror of
https://github.com/supabase/supabase.git
synced 2026-10-06 09:55:06 +03:00
Closes FE-3966 ## I have read the [CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md) file. YES ## Problem - The admonition uses both 'tip' and 'note', but the visual distinction has long-ago collapsed. - 'Note' is used far more frequently than 'tip' - The two are very similar and it is confusing to know which one to use when they are visually identical ## Solution Collapse 'tip' and 'note' into one by removing all places where there is 'tip' and updating all references to 'tip' into 'note'. **Note:** This PR also resolves new broken links flagged by the E2E docs checker. It may move to another PR since E2Es keep erroring. ### Specific changes See below for an AI-generated list of changes: - **Type system** — removed `'tip'` from `AdmonitionType`, its `TYPE_TO_VARIANT`/`TYPE_LABEL` entries, and the test case in [`packages/ui-patterns/src/Admonition/](packages/ui-patterns/src/Admonition/) - **Remark plugin** — [remarkAdmonition.ts](apps/docs/lib/mdx/plugins/remarkAdmonition.ts) now maps mkdocs `tip` → `note` - **Lint allowlist** — `tip` dropped from `supa-mdx-lint.config.toml` - **Content migration** — all 109 files with `type="tip"` (across `apps/docs`, `apps/www`, `apps/studio`) converted to `type="note"`; zero remaining hits confirmed by repo-wide grep - **Style guide** — `CONTRIBUTING.md` and `contributing/content.mdx` updated to describe 4 admonition types instead of 5 ### Usage before implementation See the usage table that points toward 'note' as being dominant across all apps: Here's the usage table: | Location | `note` | `tip` | |---|---|---| | apps/docs | ~480 | ~143 | | apps/studio | 34 | 6 | | apps/www (blog) | 19 | 3 | | packages/ui-patterns (tests) | 3 | 1 (parametrized) | | design-system / ui-library / packages/ui / packages/common | 0–1 (test fixture only) | 0 | ## Preview links | App | Page | Search text (Ctrl+F) | Verify | |---|---|---|---| | docs | [/docs/guides/ai-tools/byo-mcp](https://docs-git-admonition-collapse-note-tip-supabase.vercel.app/docs/guides/ai-tools/byo-mcp) | official MCP TypeScript SDK | callout's aria-label="Note" | | docs | [/docs/guides/ai-tools/mcp](https://docs-git-admonition-collapse-note-tip-supabase.vercel.app/docs/guides/ai-tools/mcp) | MCP server is available at | callout's aria-label="Note" | | docs | [/docs/guides/ai/python-clients](https://docs-git-admonition-collapse-note-tip-supabase.vercel.app/docs/guides/ai/python-clients) | Click Connect at the top of any project page | callout's aria-label="Note" | | docs | [/docs/guides/auth/audit-logs](https://docs-git-admonition-collapse-note-tip-supabase.vercel.app/docs/guides/auth/audit-logs) | Disabling Postgres storage reduces your database storage costs | callout's aria-label="Note" | | docs | [/docs/guides/database/tables](https://docs-git-admonition-collapse-note-tip-supabase.vercel.app/docs/guides/database/tables) | access a custom schema through the Supabase Data API | callout's aria-label="Note" | | docs | [/docs/guides/troubleshooting/edge-function-404-error-response](https://docs-git-admonition-collapse-note-tip-supabase.vercel.app/docs/guides/troubleshooting/edge-function-404-error-response) | Always configure an appropriate time frame | callout's aria-label="Note" (was single-quoted type='tip') | | www | [blog: cli-v2-config-as-code](https://zone-www-dot-com-git-admonition-collapse-note-tip-supabase.vercel.app/blog/cli-v2-config-as-code) | Detecting config drift | callout's aria-label="Note" | | www | [blog: cli-v2-config-as-code](https://zone-www-dot-com-git-admonition-collapse-note-tip-supabase.vercel.app/blog/cli-v2-config-as-code) | Setting Edge Function secrets | callout's aria-label="Note" | | www | [blog: nosql-mongodb-compatibility-with-ferretdb-and-flydotio](https://zone-www-dot-com-git-admonition-collapse-note-tip-supabase.vercel.app/blog/nosql-mongodb-compatibility-with-ferretdb-and-flydotio) | If your network supports IPv6 connections | callout's aria-label="Note" | Note: the `www` rows use the `zone-www-dot-com` preview host, not the `docs` one you gave — since blog pages are served from the www app, not docs. ## Manual testing 1. Open preview links for affected pages. 2. Inspect. Open console. 3. Paste the following in and see there is no 'Tip' on the page: ``` document.querySelectorAll('[role="alert"]').forEach(el => console.log(el.getAttribute('aria-label'), el.textContent.slice(0,60))) ``` <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Documentation** * Standardized informational callouts across docs and tutorials from **“Tip”** to **“Note”**, updating multiple examples and guidance blocks. * Updated a few related doc references/links and conditional “Next steps” content. * **UI Updates** * Switched various in-app banners and notices to the **“Note”** style variant. * **Bug Fixes / Improvements** * Removed support for the retired **“Tip”** callout type and aligned docs linting, component behavior, and aria labeling to the remaining admonition types. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
280 lines
7.8 KiB
Plaintext
280 lines
7.8 KiB
Plaintext
---
|
|
title: 'Build a User Management App with SvelteKit'
|
|
description: 'Learn how to use Supabase in your SvelteKit App.'
|
|
---
|
|
|
|
<$Partial path="quickstart_intro.mdx" />
|
|
|
|

|
|
|
|
<Admonition type="note">
|
|
|
|
If you get stuck while working through this guide, you can find the [full example on GitHub](https://github.com/supabase/supabase/tree/master/examples/user-management/sveltekit-user-management).
|
|
|
|
</Admonition>
|
|
|
|
<$Partial path="project_setup.mdx" variables={{ "framework": "sveltekit", "tab": "frameworks" }} />
|
|
|
|
## Building the app
|
|
|
|
Start building the Svelte app from scratch.
|
|
|
|
### Initialize a Svelte app
|
|
|
|
Use the [SvelteKit Skeleton Project](https://svelte.dev/docs/kit) to initialize an app called `supabase-sveltekit` (for this tutorial, select "SvelteKit minimal" and use TypeScript):
|
|
|
|
```bash
|
|
npx sv create supabase-sveltekit
|
|
cd supabase-sveltekit
|
|
npm install
|
|
```
|
|
|
|
Then install the Supabase client library: [supabase-js](https://github.com/supabase/supabase-js)
|
|
|
|
```bash
|
|
npm install @supabase/supabase-js
|
|
```
|
|
|
|
And finally, save the environment variables in a `.env` file.
|
|
All you need are the `PUBLIC_SUPABASE_URL` and the key that you copied [earlier](#get-api-details).
|
|
|
|
<$CodeTabs>
|
|
|
|
```bash name=.env
|
|
PUBLIC_SUPABASE_URL="YOUR_SUPABASE_URL"
|
|
PUBLIC_SUPABASE_PUBLISHABLE_KEY="YOUR_SUPABASE_PUBLISHABLE_KEY"
|
|
```
|
|
|
|
</$CodeTabs>
|
|
|
|
### App styling (optional)
|
|
|
|
An optional step is to update the CSS file `src/styles.css` to make the app look nice.
|
|
You can find the full contents of this file [in the example repository](https://raw.githubusercontent.com/supabase/supabase/master/examples/user-management/sveltekit-user-management/src/styles.css).
|
|
|
|
### Creating a Supabase client for SSR
|
|
|
|
The `ssr` package configures Supabase to use Cookies, which are required for server-side languages and frameworks.
|
|
|
|
Install the SSR package:
|
|
|
|
```bash
|
|
npm install @supabase/ssr
|
|
```
|
|
|
|
Creating a Supabase client with the `ssr` package automatically configures it to use Cookies. This means the user's session is available throughout the entire SvelteKit stack - page, layout, server, and hooks.
|
|
|
|
Add the code below to a `src/hooks.server.ts` file to initialize the client on the server:
|
|
|
|
<$CodeTabs>
|
|
|
|
<$CodeSample
|
|
path="/user-management/sveltekit-user-management/src/hooks.server.ts"
|
|
lines={[[1, -1]]}
|
|
meta="name=src/hooks.server.ts"
|
|
/>
|
|
|
|
</$CodeTabs>
|
|
|
|
<$Partial path="get_session_warning.mdx" />
|
|
{/* TODO: Change when adding JS autoconversion */}
|
|
As this tutorial uses TypeScript the compiler complains about `event.locals.supabase`. You can fix this by updating the `src/app.d.ts` with the content below:
|
|
|
|
<$CodeTabs>
|
|
|
|
<$CodeSample
|
|
path="/user-management/sveltekit-user-management/src/app.d.ts"
|
|
lines={[[1, -1]]}
|
|
meta="name=src/app.d.ts"
|
|
/>
|
|
|
|
</$CodeTabs>
|
|
|
|
Create a new `src/routes/+layout.server.ts` file to handle the session on the server-side.
|
|
|
|
<$CodeTabs>
|
|
|
|
<$CodeSample
|
|
path="/user-management/sveltekit-user-management/src/routes/+layout.server.ts"
|
|
lines={[[1, -1]]}
|
|
meta="name=src/routes/+layout.server.ts"
|
|
/>
|
|
|
|
</$CodeTabs>
|
|
|
|
<Admonition type="note">
|
|
|
|
Start the dev server (`npm run dev`) to generate the `./$types` files we are referencing in our project.
|
|
|
|
</Admonition>
|
|
|
|
Create a new `src/routes/+layout.ts` file to handle the session and the `supabase` object on the client-side.
|
|
|
|
<$CodeTabs>
|
|
|
|
<$CodeSample
|
|
path="/user-management/sveltekit-user-management/src/routes/+layout.ts"
|
|
lines={[[1, -1]]}
|
|
meta="name=src/routes/+layout.ts"
|
|
/>
|
|
|
|
</$CodeTabs>
|
|
|
|
Create `src/routes/+layout.svelte`:
|
|
|
|
<$CodeTabs>
|
|
|
|
<$CodeSample
|
|
path="/user-management/sveltekit-user-management/src/routes/+layout.svelte"
|
|
lines={[[1, -1]]}
|
|
meta="name=src/routes/+layout.svelte"
|
|
/>
|
|
|
|
</$CodeTabs>
|
|
|
|
### Set up a login page
|
|
|
|
Create a magic link login/signup page for your application by updating the `routes/+page.svelte` file:
|
|
|
|
<$CodeTabs>
|
|
|
|
<$CodeSample
|
|
path="/user-management/sveltekit-user-management/src/routes/+page.svelte"
|
|
lines={[[1, -1]]}
|
|
meta="name=src/routes/+page.svelte"
|
|
/>
|
|
|
|
</$CodeTabs>
|
|
|
|
Create a `src/routes/+page.server.ts` file that handles the magic link form when submitted.
|
|
|
|
<$CodeTabs>
|
|
|
|
<$CodeSample
|
|
path="/user-management/sveltekit-user-management/src/routes/+page.server.ts"
|
|
lines={[[1, -1]]}
|
|
meta="name=src/routes/+page.server.ts"
|
|
/>
|
|
|
|
</$CodeTabs>
|
|
|
|
#### Email template
|
|
|
|
Change the email template to support a server-side authentication flow.
|
|
|
|
Before proceeding, change the email template to support sending a token hash:
|
|
|
|
- Go to the [**Auth** > **Emails**](/dashboard/project/_/auth/templates) page in the project dashboard.
|
|
- Select the **Confirm signup** template.
|
|
- Change `{{ .ConfirmationURL }}` to `{{ .SiteURL }}/auth/confirm?token_hash={{ .TokenHash }}&type=email`.
|
|
- Repeat the previous step for **Magic link** template.
|
|
|
|
<Admonition type="note" title="Did you know?">
|
|
|
|
You can also customize emails sent out to new users, including the email's looks, content, and query parameters. Check out the [settings of your project](/dashboard/project/_/auth/templates).
|
|
|
|
</Admonition>
|
|
|
|
#### Confirmation endpoint
|
|
|
|
As this is a server-side rendering (SSR) environment, you need to create a server endpoint responsible for exchanging the `token_hash` for a session.
|
|
|
|
The following code snippet performs the following steps:
|
|
|
|
- Retrieves the `token_hash` sent back from the Supabase Auth server using the `token_hash` query parameter.
|
|
- Exchanges this `token_hash` for a session, which you store in storage (in this case, cookies).
|
|
- Finally, redirect the user to the `account` page or the `error` page.
|
|
|
|
<$CodeTabs>
|
|
|
|
<$CodeSample
|
|
path="/user-management/sveltekit-user-management/src/routes/auth/confirm/+server.ts"
|
|
lines={[[1, -1]]}
|
|
meta="name=src/routes/auth/confirm/+server.ts"
|
|
/>
|
|
|
|
</$CodeTabs>
|
|
|
|
#### Authentication error page
|
|
|
|
If there is an error with confirming the token, redirect the user to an error page.
|
|
|
|
<$CodeTabs>
|
|
<$CodeSample
|
|
path="/user-management/sveltekit-user-management/src/routes/auth/error/+page.svelte"
|
|
lines={[[1, -1]]}
|
|
meta="name=src/routes/auth/error/+page.svelte"
|
|
/>
|
|
|
|
</$CodeTabs>
|
|
|
|
#### Account page
|
|
|
|
After a user signs in, they need to be able to edit their profile details page.
|
|
Create a new `src/routes/account/+page.svelte` file with the content below.
|
|
|
|
<$CodeTabs>
|
|
|
|
<$CodeSample
|
|
path="/user-management/sveltekit-user-management/src/routes/account/+page.svelte"
|
|
lines={[[1, 3],[6,12],[15,38],[49,-1]]}
|
|
meta="name=src/routes/account/+page.svelte"
|
|
/>
|
|
|
|
</$CodeTabs>
|
|
|
|
Now, create the associated `src/routes/account/+page.server.ts` file that handles loading data from the server through the `load` function
|
|
and handle all form actions through the `actions` object.
|
|
|
|
<$CodeSample
|
|
path="/user-management/sveltekit-user-management/src/routes/account/+page.server.ts"
|
|
lines={[[1, -1]]}
|
|
meta="name=src/routes/account/+page.server.ts"
|
|
/>
|
|
|
|
## Profile photos
|
|
|
|
Next, add a way for users to upload a profile photo. Supabase configures every project with [Storage](/docs/guides/storage) for managing large files like photos and videos.
|
|
|
|
### Create an upload widget
|
|
|
|
Start by creating a new component called `Avatar.svelte` in the `src/routes/account` directory:
|
|
|
|
<$CodeTabs>
|
|
|
|
<$CodeSample
|
|
path="/user-management/sveltekit-user-management/src/routes/account/Avatar.svelte"
|
|
lines={[[1, -1]]}
|
|
meta="name=src/routes/account/Avatar.svelte"
|
|
/>
|
|
|
|
</$CodeTabs>
|
|
|
|
### Update the account page
|
|
|
|
With the Avatar component created, update `src/routes/account/+page.svelte` to include it:
|
|
|
|
<$CodeTabs>
|
|
|
|
<$CodeSample
|
|
path="/user-management/sveltekit-user-management/src/routes/account/+page.svelte"
|
|
lines={[[1, -1]]}
|
|
meta="name=src/routes/account/+page.svelte"
|
|
/>
|
|
|
|
</$CodeTabs>
|
|
|
|
### Launch!
|
|
|
|
With all the pages in place, run this command in a terminal:
|
|
|
|
```bash
|
|
npm run dev
|
|
```
|
|
|
|
And then open the browser to [localhost:5173](http://localhost:5173) and you should see the completed app.
|
|
|
|

|
|
|
|
At this stage you have a fully functional application!
|