With Webflow sunsetting its native User Accounts feature, many developers face the challenge of finding a secure, robust, and easy-to-integrate solution. Now, imagine you're building a loyalty program website—a vibrant digital haven where members effortlessly log in to check their personalized content and track their reward points. Your community is excited to explore exclusive benefits and see their progress, but with the traditional authentication method gone, how do you ensure a flawless, secure experience?
Enter Authgear. This powerful tool steps in to bridge the gap left by Webflow. Authgear’s generous free tier and versatile suite of features make it the ideal replacement for managing user authentication on your loyalty program site. Whether you’re a seasoned developer or just beginning your journey, integrating Authgear ensures your members can seamlessly log in, interact with exclusive content, and feel secure every step of the way.
In this guide, you’ll embark on a step-by-step process to integrate Authgear into your Webflow website. By the end, you’ll have learned to:
- Create an Authgear project and an application.
- Add Login, Logout, and Sign Up buttons that show/hide correctly.
- Implement the core authentication logic for your Webflow site.
- Display standard and custom user information in a protected section.
- Create and manage gated content visible only to logged-in users.
You can check the end product of this guide in here, you can also clone the Webflow project here.
Prerequisites
- An active Authgear account. If you don't have one, you can sign up for free.
- A Webflow account and a project you want to add authentication to.
Step 1: Create Your Authgear Project
First, we'll create a project, which acts as a container for your applications and users.
- After signing into the Authgear Portal, you will be prompted to create a new project.
- Enter a Project Name (e.g.,
My Webflow Site
). - Complete the endpoint domain to form your unique Authgear endpoint:
https://<your-project-name>.authgear.cloud
. Click "Next".

- Choose how you would like your end-users to login. In this tutorial, make sure we choose Email here.
- Add branding by uploading logo and choosing the colors you like.
Step 2: Create and Configure an Application
Now that you have a project, you need to create an application within it.
- In the Authgear Portal, navigate to Applications in the left-hand menu.
- Click the + Add Application button in the top toolbar.
- In the dialog, enter an Application Name (e.g., "Webflow Site") and select the Single Page Application type. Click "Save".

- On the next screen, Authgear shows tutorials for various frameworks. Click Next to skip this and go to your application's configuration page.
- You will now be on the application configuration page. Under the URIs section, find the Authorized Redirect URIs field.
- Enter the root URL of your published Webflow site (e.g.,
https://my-awesome-site.webflow.io/
). Note that the trailing "/" in the above URLs must be included. - Click Save at the bottom of the page.
- Finally, make a note on your Client ID and Endpoint. You will need these values in a later step.

Step 3: Add Custom Styles to Webflow
- In your Webflow project, go to Site Settings > Custom Code.
- In the Head Code section, paste the CSS styles below. These styles prevent a "flash" of content before our script has a chance to run. The script itself will be added to the footer in the next step for better page performance.
1<!-- Initial Visibility Styles -->
2<style>
3 .auth---visible, .auth---invisible {
4 visibility: hidden;
5 }
6 .hidden {
7 display: none !important;
8 }
9</style>
- Click "Save Changes".
Step 4: Add the SDK and Style Authentication Buttons
- In the Webflow Designer, add three Button elements to your page.
- Set their text to "Login", "Sign Up", and "Logout".
- Assign classes and IDs:
- Login Button: Class
auth---invisible
, IDlogin-btn
- Sign Up Button: Class
auth---invisible
, IDsignup-btn
- Logout Button: Class
auth---visible
, IDlogout-btn
- Login Button: Class
- Go back to Site Settings > Custom Code and paste the following into the Footer Code section. This includes the Authgear SDK and the initial logic for your buttons.
1<!-- Authgear Web SDK -->
2<script src="https://unpkg.com/@authgear/web@2.2.0/dist/authgear-web.iife.js"></script>
3
4<script>
5const login = () => { console.log("Login button clicked."); };
6const logout = () => { console.log("Logout button clicked."); };
7
8const addClickListeners = () => {
9 document.querySelector("#login-btn")?.addEventListener("click", login);
10 document.querySelector("#signup-btn")?.addEventListener("click", login);
11 document.querySelector("#logout-btn")?.addEventListener("click", logout);
12};
13
14window.onload = () => {
15 addClickListeners();
16};
17</script>
Step 5: Implement the Core Authentication and UI Logic
Update the Footer Code:
In your Webflow Footer Code, replace the contents of the second <script>
tag with the full logic below. Remember to update the placeholder values with your credentials from Step 2.
1// --- Authgear Configuration ---
2let authgearClient = null;
3
4const configureClient = async () => {
5 authgearClient = window.authgear.default;
6 await authgearClient.configure({
7 endpoint: "<YOUR_AUTHGEAR_PROJECT_DOMAIN>",
8 clientID: "<YOUR_AUTHGEAR_APP_CLIENT_ID>",
9 sessionType: "refresh_token",
10 }).then(
11 () => { console.log("Authgear client successfully configured!"); },
12 (err) => { console.log("Failed to configure Authgear", err); }
13 );
14};
15
16// --- Authentication Functions ---
17const login = () => {
18 try {
19 console.log("Redirecting to login...");
20 const targetURL = `${window.location.origin}/`;
21 authgearClient.startAuthentication({ redirectURI: targetURL, prompt: "login" });
22 } catch (err) { console.log("Login failed", err); }
23};
24
25const logout = () => {
26 try {
27 console.log("Logging out");
28 authgearClient.logout({
29 redirectURI: window.location.origin
30 }).then(
31 () => { updateUI(); },
32 (err) => { console.log("Logout failed", err); }
33 );
34 } catch (err) { console.log("Log out failed", err); }
35};
36
37// --- UI Control ---
38const eachElement = (selector, fn) => {
39 for (let e of document.querySelectorAll(selector)) { fn(e); }
40};
41
42const updateUI = async () => {
43 const isAuthenticated = authgearClient.sessionState === "AUTHENTICATED";
44 if (isAuthenticated) {
45 eachElement(".auth---invisible", (e) => e.classList.add("hidden"));
46 eachElement(".auth---visible", (e) => {
47 e.classList.remove("hidden");
48 e.style.visibility = "visible";
49 });
50 } else {
51 if (document.body.classList.contains("auth---visible")) { window.location.replace("/"); }
52 eachElement(".auth---invisible", (e) => {
53 e.classList.remove("hidden");
54 e.style.visibility = "visible";
55 });
56 eachElement(".auth---visible", (e) => e.classList.add("hidden"));
57 }
58};
59
60// --- Event Listeners and Page Load ---
61const addClickListeners = () => {
62 document.querySelector("#login-btn")?.addEventListener("click", login);
63 document.querySelector("#signup-btn")?.addEventListener("click", login);
64 document.querySelector("#logout-btn")?.addEventListener("click", logout);
65};
66
67window.onload = async () => {
68 await configureClient();
69 addClickListeners();
70 try {
71 if (window.location.search.includes("code=")) {
72 await authgearClient.finishAuthentication();
73 window.history.replaceState({}, document.title, window.location.pathname);
74 }
75 } catch {}
76 try {
77 await authgearClient.refreshAccessToken();
78 } catch {}
79 finally {
80 console.log("Authgear Session State:", authgearClient.sessionState);
81 updateUI();
82 }
83};
Then, you can move on to sign up as the first user:
- Publish your Webflow site.
- Open the live site URL and click "Sign Up" to create an account.
- After signing up, you will be redirected back, and the "Logout" button should be visible.
- Verify this new user exists in your Authgear Admin Portal under User Management > Users.
Step 6: Add Elements for Standard User Information
- In the Webflow Designer, add two Paragraph elements to your page.
- Assign them IDs and text:
- First Paragraph: ID
user-email
, Text Membership Email: - Second Paragraph: ID
user-email-verified
, Text Verification Status:
- First Paragraph: ID
- In your Footer Code, update the
updateUI
function to fetch and append this data.
1const updateUI = async () => {
2 const isAuthenticated = authgearClient.sessionState === "AUTHENTICATED";
3 if (isAuthenticated) {
4 eachElement(".auth---invisible", (e) => e.classList.add("hidden"));
5 eachElement(".auth---visible", (e) => {
6 e.classList.remove("hidden");
7 e.style.visibility = "visible";
8 });
9 // --- THIS PART IS NEW ---
10 try {
11 const userInfo = await authgearClient.fetchUserInfo();
12 document.getElementById("user-email").textContent += ` ${userInfo.email}`;
13 document.getElementById("user-email-verified").textContent += ` ${userInfo.emailVerified ? "Verified" : "Not Verified"}`;
14 } catch (error) { console.error("Failed to fetch user info:", error); }
15 // --- END NEW PART ---
16 } else { // ... else logic from step 5
17 if (document.body.classList.contains("auth---visible")) { window.location.replace("/"); }
18 eachElement(".auth---invisible", (e) => {
19 e.classList.remove("hidden");
20 e.style.visibility = "visible";
21 });
22 eachElement(".auth---visible", (e) => e.classList.add("hidden"));
23 }
24};
Step 7: Add and Display Custom Attributes
7a. Create, Configure, and Assign a Custom Attribute
- Define the Attribute:
- In the Authgear Admin Portal, navigate to User Profile > Custom Attributes.
- Click "+ Add New Attribute".
- Configure it: Name
points_collected
, Type Number. Click "Save". - In the list, set Token Bearer Access Right and End-user Access Right to Read-only.

- Assign a Value to Your User
- Navigate to User Management > Users, and click on your test user.
- In the Profile Tab, scroll down to Custom Attributes.
- Enter a number (e.g., 50) in the Points Collected field and click "Save".

7b. Display the Custom Attribute in Webflow
- In the Webflow Designer, add a new Paragraph element to your page.
- Give it the ID
points-collected
and set its text to FlowPoints Collected:. - In your Footer Code, update the
updateUI
function again to fetch and display this value.
1const updateUI = async () => {
2 // ...
3 if (isAuthenticated) {
4 // ...
5 try {
6 const userInfo = await authgearClient.fetchUserInfo();
7 document.getElementById("user-email").textContent += ` ${userInfo.email}`;
8 document.getElementById("user-email-verified").textContent += ` ${userInfo.emailVerified ? "Verified" : "Not Verified"}`;
9
10 // --- THIS PART IS NEW ---
11 const points = userInfo.customAttributes?.points_collected ?? 0;
12 document.getElementById("points-collected").textContent += ` ${points}`;
13 // --- END NEW PART ---
14
15 } catch (error) { console.error("Failed to fetch user info:", error); }
16 }
17 // ...
18};
Step 8: Protect Content
8a. Protect a Section of a Page
- In the Webflow Designer, add a Div Block to your page for the "logged out" view.
- Give it the class
a
uth---invisible
. - Inside, add a Paragraph with the text "Please login to see this locked content".
- Add a Button with the text "Login to View" and the class
content-button
.
- Give it the class
- Add a second Div Block for the "logged in" view.
- Give it the class
auth---visible
. - Drag the three paragraph elements from Steps 6 and 7 inside this div.
- Give it the class
- Finally, add a click listener for the new
content-button
.
1const addClickListeners = () => {
2 document.querySelector("#login-btn")?.addEventListener("click", login);
3 document.querySelector("#signup-btn")?.addEventListener("click", login);
4 document.querySelector("#logout-btn")?.addEventListener("click", logout);
5 // This line is new
6 document.querySelector(".content-button")?.addEventListener("click", login);
7};
8b. Protect an Entire Page
- Create a new page in Webflow (e.g., "locked-content").
- In the Navigator panel, select the Body element.
- In the Style Panel (S), give the Body the class
auth---visible
. Our script will now automatically redirect any unauthenticated users from this page.
Final Code
Here is the complete, final script to be placed in your Webflow project's Footer Code.
1<!-- Authgear Web SDK -->
2<script src="https://unpkg.com/@authgear/web@2.2.0/dist/authgear-web.iife.js"></script>
3
4<script>
5let authgearClient = null;
6
7const configureClient = async () => {
8 authgearClient = window.authgear.default;
9 await authgearClient.configure({
10 endpoint: "<YOUR_AUTHGEAR_PROJECT_DOMAIN>",
11 clientID: "<YOUR_AUTHGEAR_APP_CLIENT_ID>",
12 sessionType: "refresh_token",
13 }).then(
14 () => { console.log("Authgear client successfully configured!"); },
15 (err) => { console.log("Failed to configure Authgear", err); }
16 );
17};
18
19const login = () => {
20 try {
21 console.log("Redirecting to login...");
22 const targetURL = `${window.location.origin}/`;
23 authgearClient.startAuthentication({ redirectURI: targetURL, prompt: "login" });
24 } catch (err) { console.log("Login failed", err); }
25};
26
27const logout = () => {
28 try {
29 console.log("Logging out");
30 authgearClient.logout({
31 redirectURI: window.location.origin
32 }).then(
33 () => {
34 // logged out successfully
35 updateUI();
36 },
37 (err) => {
38 // failed to logout
39 console.log("Logout failed", err);
40 }
41 );
42 } catch (err) {
43 console.log("Log out failed", err);
44 }
45};
46
47const eachElement = (selector, fn) => {
48 for (let e of document.querySelectorAll(selector)) { fn(e); }
49};
50
51const updateUI = async () => {
52 const isAuthenticated = authgearClient.sessionState === "AUTHENTICATED";
53
54 if (isAuthenticated) {
55 eachElement(".auth---invisible", (e) => e.classList.add("hidden"));
56 eachElement(".auth---visible", (e) => {
57 e.classList.remove("hidden");
58 e.style.visibility = "visible";
59 });
60
61 try {
62 const userInfo = await authgearClient.fetchUserInfo();
63 // Clear previous data to prevent duplication on UI refreshes
64 document.getElementById("user-email").textContent = 'Membership Email:';
65 document.getElementById("user-email-verified").textContent = 'Verification Status:';
66 document.getElementById("points-collected").textContent = 'FlowPoints Collected:';
67
68 // Append new data
69 document.getElementById("user-email").textContent += ` ${userInfo.email}`;
70 document.getElementById("user-email-verified").textContent += ` ${userInfo.emailVerified ? "Verified" : "Not Verified"}`;
71 const points = userInfo.customAttributes?.points_collected ?? 0;
72 document.getElementById("points-collected").textContent += ` ${points}`;
73 } catch (error) { console.error("Failed to fetch user info:", error); }
74
75 } else {
76 if (document.body.classList.contains("auth---visible")) {
77 window.location.replace("/");
78 }
79 eachElement(".auth---invisible", (e) => {
80 e.classList.remove("hidden");
81 e.style.visibility = "visible";
82 });
83 eachElement(".auth---visible", (e) => e.classList.add("hidden"));
84 }
85};
86
87const addClickListeners = () => {
88 document.querySelector("#login-btn")?.addEventListener("click", login);
89 document.querySelector("#signup-btn")?.addEventListener("click", login);
90 document.querySelector("#logout-btn")?.addEventListener("click", logout);
91 document.querySelector(".content-button")?.addEventListener("click", login);
92};
93
94window.onload = async () => {
95 await configureClient();
96 addClickListeners();
97
98 try {
99 if (window.location.search.includes("code=")) {
100 await authgearClient.finishAuthentication();
101 window.history.replaceState({}, document.title, window.location.pathname);
102 }
103 } catch {}
104
105 // `refreshAccessToken` ensures the session information is up-to-date.
106 try {
107 await authgearClient.refreshAccessToken();
108 } catch {
109 // It's normal for this to fail for logged-out users. We can safely ignore the error.
110 } finally {
111 // Update the UI. This `finally` block runs regardless of whether
112 // the user was logged in or not, ensuring the UI is always correct.
113 console.log("Authgear Session State:", authgearClient.sessionState);
114 updateUI();
115 }
116};
117</script>
Conclusion
By following this guide, you’ve seen how Authgear can seamlessly fill the gap left by Webflow’s native User Accounts, enabling you to offer secure, intuitive authentication and personalized experiences for your users. With features like easy integration, customizable UI, and robust user management, Authgear empowers you to protect your content and build thriving communities with confidence.
Ready to secure your Webflow site and delight your users? Sign up for Authgear for free and start building today!