> ## Documentation Index
> Fetch the complete documentation index at: https://usegately.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Webflow Integration

> Add authentication and user management to your Webflow site

Integrate Gately with your Webflow site to add user authentication, protected content, and member management.

## Quick Setup

<Steps>
  <Step title="Add the SDK">
    In Webflow, go to **Project Settings > Custom Code** and add to the **Head Code**:

    ```html theme={null}
    <script 
      src="https://cdn.usegately.com/gately.min.js" 
      data-project-id="YOUR_PROJECT_ID"
      defer
    ></script>
    ```
  </Step>

  <Step title="Add Custom Attributes">
    Use Webflow's custom attributes to mark protected content.
  </Step>

  <Step title="Add Footer Scripts">
    Add interaction scripts to the **Footer Code** section.
  </Step>
</Steps>

## Login Form

### HTML Structure

Create a form in Webflow with these elements:

* Email input with ID `login-email`
* Password input with ID `login-password`
* Submit button with ID `login-submit`
* Error message div with ID `login-error`

### JavaScript

Add to **Footer Code**:

```html theme={null}
<script>
document.addEventListener('DOMContentLoaded', function() {
  const form = document.getElementById('login-form');
  const emailInput = document.getElementById('login-email');
  const passwordInput = document.getElementById('login-password');
  const submitBtn = document.getElementById('login-submit');
  const errorDiv = document.getElementById('login-error');

  if (form) {
    form.addEventListener('submit', async function(e) {
      e.preventDefault();
      
      submitBtn.disabled = true;
      submitBtn.textContent = 'Logging in...';
      errorDiv.style.display = 'none';

      try {
        await window.Gately.login(emailInput.value, passwordInput.value);
        window.location.href = '/dashboard';
      } catch (error) {
        errorDiv.textContent = error.message;
        errorDiv.style.display = 'block';
        submitBtn.disabled = false;
        submitBtn.textContent = 'Log In';
      }
    });
  }
});
</script>
```

## Signup Form

### HTML Structure

Create a form with:

* Name input with ID `signup-name`
* Email input with ID `signup-email`
* Password input with ID `signup-password`
* Submit button with ID `signup-submit`
* Error message div with ID `signup-error`

### JavaScript

```html theme={null}
<script>
document.addEventListener('DOMContentLoaded', function() {
  const form = document.getElementById('signup-form');
  const nameInput = document.getElementById('signup-name');
  const emailInput = document.getElementById('signup-email');
  const passwordInput = document.getElementById('signup-password');
  const submitBtn = document.getElementById('signup-submit');
  const errorDiv = document.getElementById('signup-error');

  if (form) {
    form.addEventListener('submit', async function(e) {
      e.preventDefault();
      
      submitBtn.disabled = true;
      submitBtn.textContent = 'Creating account...';
      errorDiv.style.display = 'none';

      try {
        await window.Gately.signup(emailInput.value, passwordInput.value, {
          full_name: nameInput.value
        });
        window.location.href = '/dashboard';
      } catch (error) {
        errorDiv.textContent = error.message;
        errorDiv.style.display = 'block';
        submitBtn.disabled = false;
        submitBtn.textContent = 'Sign Up';
      }
    });
  }
});
</script>
```

## Protected Content

### Using Custom Attributes

In Webflow, add custom attributes to elements:

| Attribute               | Value       | Description            |
| ----------------------- | ----------- | ---------------------- |
| `data-gately-protected` | (empty)     | Requires login         |
| `data-gately-plan`      | `pro`       | Requires specific plan |
| `data-gately-show-if`   | `logged-in` | Show only if logged in |
| `data-gately-hide-if`   | `logged-in` | Hide if logged in      |

### JavaScript for Visibility

```html theme={null}
<script>
document.addEventListener('DOMContentLoaded', function() {
  function updateVisibility() {
    const isLoggedIn = window.Gately && window.Gately.isAuthenticated();
    const user = isLoggedIn ? window.Gately.getUser() : null;

    // Show/hide based on login status
    document.querySelectorAll('[data-gately-show-if="logged-in"]').forEach(el => {
      el.style.display = isLoggedIn ? '' : 'none';
    });

    document.querySelectorAll('[data-gately-hide-if="logged-in"]').forEach(el => {
      el.style.display = isLoggedIn ? 'none' : '';
    });

    // Protected content
    document.querySelectorAll('[data-gately-protected]').forEach(el => {
      if (!isLoggedIn) {
        el.innerHTML = '<p>Please <a href="/login">log in</a> to view this content.</p>';
      }
    });

    // Plan-based content
    document.querySelectorAll('[data-gately-plan]').forEach(el => {
      const requiredPlan = el.getAttribute('data-gately-plan');
      if (!user || user.plan_id !== requiredPlan) {
        el.innerHTML = '<p>Upgrade to ' + requiredPlan + ' to access this content.</p>';
      }
    });
  }

  // Run on load
  updateVisibility();

  // Listen for auth changes
  if (window.Gately) {
    window.Gately.onAuthStateChange(updateVisibility);
  }
});
</script>
```

## Social Login Buttons

### Google Login

```html theme={null}
<a href="#" id="google-login-btn" class="social-btn">
  <img src="/google-icon.svg" alt="Google" />
  Continue with Google
</a>

<script>
document.getElementById('google-login-btn').addEventListener('click', function(e) {
  e.preventDefault();
  window.Gately.loginWithGoogle({ redirectTo: '/dashboard' });
});
</script>
```

### GitHub Login

```html theme={null}
<a href="#" id="github-login-btn" class="social-btn">
  <img src="/github-icon.svg" alt="GitHub" />
  Continue with GitHub
</a>

<script>
document.getElementById('github-login-btn').addEventListener('click', function(e) {
  e.preventDefault();
  window.Gately.loginWithGithub({ redirectTo: '/dashboard' });
});
</script>
```

## User Profile Display

```html theme={null}
<div id="user-profile" style="display: none;">
  <img id="user-avatar" src="" alt="Avatar" />
  <span id="user-name"></span>
  <a href="#" id="logout-btn">Log Out</a>
</div>

<script>
document.addEventListener('DOMContentLoaded', function() {
  function updateProfile() {
    const profileDiv = document.getElementById('user-profile');
    const user = window.Gately ? window.Gately.getUser() : null;

    if (user) {
      profileDiv.style.display = 'flex';
      document.getElementById('user-name').textContent = user.full_name || user.email;
      
      if (user.avatar_url) {
        document.getElementById('user-avatar').src = user.avatar_url;
      }
    } else {
      profileDiv.style.display = 'none';
    }
  }

  updateProfile();
  
  if (window.Gately) {
    window.Gately.onAuthStateChange(updateProfile);
  }

  document.getElementById('logout-btn').addEventListener('click', async function(e) {
    e.preventDefault();
    await window.Gately.logout();
    window.location.href = '/';
  });
});
</script>
```

## Page Protection

Protect entire pages by adding to the page's custom code:

```html theme={null}
<script>
document.addEventListener('DOMContentLoaded', function() {
  if (!window.Gately || !window.Gately.isAuthenticated()) {
    window.location.href = '/login?redirect=' + encodeURIComponent(window.location.pathname);
  }
});
</script>
```

## Best Practices

<AccordionGroup>
  <Accordion title="Use Webflow Interactions">
    Combine Gately with Webflow interactions for smooth UX.
  </Accordion>

  <Accordion title="Style Error Messages">
    Create styled error message components in Webflow.
  </Accordion>

  <Accordion title="Loading States">
    Add loading animations while auth operations complete.
  </Accordion>

  <Accordion title="Mobile Responsive">
    Test auth flows on mobile devices.
  </Accordion>
</AccordionGroup>
