Skip to content

Commit 36fb4f4

Browse files
Merge branch 'main' into partners-catalog
2 parents 20d568c + 5d460db commit 36fb4f4

File tree

18 files changed

+1296
-65
lines changed

18 files changed

+1296
-65
lines changed

src/markdoc/layouts/Author.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@
163163
</div>
164164
</div>
165165

166-
<div class="py-10">
166+
<div class="pt-10">
167167
<div class="web-big-padding-section-level-2">
168168
<div class="container">
169169
<h2 class="text-title font-aeonik-pro text-primary">Articles</h2>

src/markdoc/layouts/Category.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
</svelte:head>
3838

3939
<Main>
40-
<div class="py-10">
40+
<div class="pt-10">
4141
<div class="web-big-padding-section-level-2">
4242
<div class="container">
4343
<a class="web-link web-u-color-text-secondary items-baseline" href="/blog">

src/markdoc/layouts/Integration.svelte

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@
8787
</div>
8888
</div>
8989
</div>
90-
<div class="py-10">
90+
<div class="pt-10">
9191
<div class="container">
9292
<article class="web-u-gap-60-not-mobile web-u-gap-40-mobile flex flex-col">
9393
<div class="l-grid-2-1 web-u-row-gap-56 web-u-gap-40-mobile">
@@ -143,7 +143,7 @@
143143
</div>
144144
</div>
145145

146-
<div class="web-u-sep-block-start mt-12 overflow-hidden py-10">
146+
<div class="web-u-sep-block-start mt-12 overflow-hidden pt-10">
147147
<!-- <ProductsGrid /> -->
148148

149149
<div class="container">

src/markdoc/layouts/Post.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@
119119
</svelte:head>
120120

121121
<Main>
122-
<div class="py-10">
122+
<div class="pt-10">
123123
<div class="container">
124124
<Breadcrumbs {title} />
125125
<article class="grid grid-cols-1 gap-4 lg:grid-cols-12">

src/markdoc/tags/Tabs.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@
4747
class="dark:bg-greyscale-850/90 mt-4 mb-8 flex flex-col gap-1 rounded-2xl border border-black/8 bg-white/90 px-6 pt-4 pb-6 outline-0 dark:border-white/10"
4848
>
4949
<div
50-
class="flex items-center gap-4 overflow-scroll [-ms-overflow-style:none] [scrollbard-width:none]"
50+
class="flex items-center gap-4 overflow-scroll [-ms-overflow-style:none] [scrollbar-width:none]"
5151
>
5252
<div class="hidden items-center gap-4 sm:flex" {...tabs.triggerList}>
5353
{#each $ctx.triggers.slice(0, 7) as { title, id }}
Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
---
2+
layout: post
3+
title: How to add Figma OAuth2 login to your app with Appwrite
4+
description: Learn how to set up Figma OAuth2 login to your app with Appwrite.
5+
date: 2025-05-07
6+
cover: /images/blog/add-figma-oauth2-appwrite/cover.png
7+
timeToRead: 5
8+
author: ebenezer-don
9+
category: tutorial
10+
featured: false
11+
---
12+
13+
Figma's API opens up some interesting doors, such as automating workflows, syncing design tokens, and bringing live design previews into your app. But before you can do any of that, your users need to connect their Figma account. If you're using Appwrite for authentication, this process is simpler than you might expect. In this guide, we'll walk through everything you need to do to support Figma OAuth2 login inside your Appwrite project.
14+
15+
We'll cover both the configuration and the actual login flow, then show how to securely access Figma's API on behalf of the user. You won't need any server-side code because Appwrite handles the OAuth2 flow for you, and sessions are maintained like any other login provider.
16+
17+
# Understanding the OAuth flow in Appwrite
18+
19+
When a user attempts to sign in with Figma, Appwrite starts a standard OAuth2 flow:
20+
21+
1. It redirects the user to Figma with the necessary query parameters (`client_id`, `redirect_uri`, `scope`, and `state`).
22+
2. Once the user grants access, Figma sends back an authorization code.
23+
3. Appwrite exchanges that code for an access token and refresh token.
24+
4. A new Appwrite session is created for the user.
25+
5. That session includes the user's identity and also stores the Figma tokens, so your frontend can later call the Figma API if needed.
26+
27+
The access token is used to make requests to Figma's API. Appwrite also stores the refresh token and allows you to renew the access token when it expires. This is optional and only necessary if you continue to use Figma's API beyond the initial login.
28+
29+
# Creating your OAuth app in Figma
30+
31+
To connect your Appwrite project to Figma, the first step is to register your app on the [Figma Developer Portal](https://www.figma.com/developers/apps). This allows you to request access to a user's Figma data through OAuth2.
32+
33+
Click **"Create a new app"** in the top right.
34+
35+
You'll be asked to fill in a few details:
36+
37+
- **Name** - This will be shown to users during login.
38+
- **Website** - A link to your app or landing page.
39+
- **Logo** - Optional, but it helps users recognize your app in the consent screen.
40+
41+
![Figma Create App](/images/blog/add-figma-oauth2-appwrite/figma-create-app.png)
42+
43+
Once you save the app, Figma will show your **Client ID** and **Client Secret**. These are the credentials you'll need to complete the setup in Appwrite.
44+
45+
![Figma Client ID and Secret](/images/blog/add-figma-oauth2-appwrite/figma-client-info.png)
46+
47+
Take a moment to copy both values. The **Client Secret** is shown only once, so make sure to save it somewhere you can reference later.
48+
49+
Now that the app is registered, find it in your list of apps and click to open it. Inside the modal, switch to the **OAuth 2.0** section and click **Add a redirect URL**. This is where you'll paste the callback URL that Appwrite generates in the next step.
50+
51+
Keep this tab open. We'll come right back to it.
52+
53+
# Enabling Figma as a provider in Appwrite
54+
55+
Now let's switch over to Appwrite.
56+
57+
1. Open the [Appwrite Console](https://cloud.appwrite.io/) and choose your project.
58+
2. In the left-hand sidebar, click **Auth**.
59+
3. Inside the Auth section, select the **Settings** tab.
60+
4. Scroll down to the **OAuth2 Providers** section.
61+
5. Click on **Figma**.
62+
63+
This opens a configuration panel where you'll see:
64+
65+
- A toggle to enable the Figma provider.
66+
- Input fields for **App ID** and **App Secret**.
67+
- A read-only **Redirect URI** that Appwrite will use for the callback.
68+
69+
Copy the Redirect URI and return to your Figma app configuration. Under **OAuth 2.0**, paste it into the redirect URL field and save the changes.
70+
71+
Once that's done, head back to Appwrite, paste in your **Client ID** and **Client Secret**, enable the toggle, and click **Update**.
72+
73+
![Appwrite Figma Provider](/images/blog/add-figma-oauth2-appwrite/appwrite-figma-oauth-screen.png)
74+
75+
At this point, Figma is connected to your Appwrite backend.
76+
77+
# Logging in from your frontend
78+
79+
Once Figma is enabled as a provider, you can trigger a login using the Appwrite SDK. Here's an example using the JavaScript SDK in a React app:
80+
81+
```js
82+
import { Client, Account, OAuthProvider } from 'appwrite'
83+
84+
const client = new Client()
85+
.setEndpoint('https://<REGION>.cloud.appwrite.io/v1')
86+
.setProject('your-project-id')
87+
88+
const account = new Account(client)
89+
90+
function signInWithFigma() {
91+
account.createOAuth2Session(
92+
OAuthProvider.Figma,
93+
'<https://your-app.com/redirect-after-success>',
94+
'<https://your-app.com/redirect-after-failure>',
95+
['file_read'], // scopes (optional)
96+
)
97+
}
98+
```
99+
100+
This will redirect the user to Figma's consent screen. Once they log in and approve access, they'll be returned to your app with an active Appwrite session.
101+
102+
# Calling the Figma API (if needed)
103+
104+
If your app just needs Figma for login, you don't have to think about the Figma token again. Appwrite already pulled the identity info (name, email, etc.) when the session was created.
105+
106+
But if you want to call Figma's API after the initial login, either to fetch files, sync variables, or manage libraries, you'll need a valid access token. Figma's tokens expire after 24 hours, but Appwrite stores the refresh token and gives you a way to renew them:
107+
108+
```js
109+
async function getFigmaFiles() {
110+
// Ensure token is fresh
111+
await account.updateSession('current')
112+
const session = await account.getSession('current')
113+
const token = session.providerAccessToken
114+
115+
const res = await fetch('https://api.figma.com/v1/files/file_key', {
116+
headers: {
117+
Authorization: `Bearer ${token}`,
118+
},
119+
})
120+
121+
if (!res.ok) {
122+
throw new Error('Figma API error')
123+
}
124+
125+
return res.json()
126+
}
127+
```
128+
129+
The `updateSession()` call silently refreshes the Figma token using the stored refresh token. Your user remains logged in to your app, so they won't see any interruptions.
130+
131+
# What happens when the Figma token expires?
132+
133+
Appwrite keeps the user logged in with their Appwrite session. Even after Figma's access token expires, your app's session remains valid. The only thing that stops working is the ability to make requests to Figma's API.
134+
135+
So if your app never talks to Figma again, you don't have to refresh anything. But if you need to access the API after the token has expired, calling `updateSession()` is the way to renew it.
136+
137+
# Common issues to watch for
138+
139+
**Redirect URI mismatch**
140+
If the redirect URI you added in Figma doesn't match exactly what Appwrite is using, including protocol, port, or trailing slashes, Figma will reject the login with a `redirect_uri mismatch` error.
141+
142+
**Invalid client credentials**
143+
If you see an `invalid_client` error, it usually means your Client ID or Secret is incorrect, or you didn't copy the secret when it was first shown.
144+
145+
**Expired token when calling Figma API**
146+
That's expected if the token has expired. Just call `updateSession('current')` before you hit the Figma endpoint again.
147+
148+
**Scope mismatch**
149+
Make sure the scopes you request in `createOAuth2Session()` match what you enabled in Figma. Otherwise, Figma will block the request.
150+
151+
# Logging out
152+
153+
To log the user out and remove access to their Figma account:
154+
155+
```js
156+
await account.deleteSession('current')
157+
```
158+
159+
This clears both the Appwrite session and the associated access and refresh tokens.
160+
161+
# Final thoughts
162+
163+
You don't need a custom backend to support "Sign in with Figma." Appwrite gives you a simple way to plug in Figma as an OAuth2 provider, handle authentication, and optionally access the Figma API, all with session management handled for you.
164+
165+
If you're only using Figma for sign-in, your work is done once the session is created. But if your app needs to interact with Figma's API after that, Appwrite gives you a safe way to refresh tokens on demand.
166+
167+
If you have any questions or run into any issues, feel free to reach out to the team through the [Appwrite Discord server](https://appwrite.io/discord).
168+
169+
# Further reading
170+
171+
- [Appwrite OAuth2 docs](https://appwrite.io/docs/client/auth#oauth2)
172+
- [Figma API docs](https://www.figma.com/developers/api)
173+
- [How to set up Google authentication in React with Appwrite](https://appwrite.io/blog/post/set-up-google-auth-appwrite-react)

src/routes/docs/products/auth/+layout.svelte

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,10 @@
104104
{
105105
label: 'Team invites',
106106
href: '/docs/products/auth/team-invites'
107+
},
108+
{
109+
label: 'Multi-tenancy',
110+
href: '/docs/products/auth/multi-tenancy'
107111
}
108112
]
109113
},

0 commit comments

Comments
 (0)