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

# Vanilla JavaScript

> Integrate Civic Auth into your Vanilla JavaScript application with just a few lines of code.

## Quick Start

### Prerequisites

* A Civic Auth Client ID (get it from [auth.civic.com](https://auth.civic.com))
* Configure your redirect URL in the Civic Auth dashboard (typically `http://localhost:3000` for development)

### Installation

**NPM**

```bash theme={null}
npm install @civic/auth
```

<Tip>
  We highly recommend using [Vite](https://vitejs.dev/) for the best development experience with modern JavaScript features, fast hot reloading, and seamless ES module support.

  ```bash theme={null}
  npm create vite@latest my-civic-app -- --template vanilla
  cd my-civic-app
  npm install
  npm install @civic/auth
  ```
</Tip>

### Simple Setup

1. **HTML**:

```html theme={null}
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>My App with Civic Auth</title>
  </head>
  <body>
    <h1>My App</h1>

    <button id="loginButton">Sign In</button>
    <button id="logoutButton">Sign Out</button>

    <!-- Only needed for embedded display mode -->
    <div id="authContainer"></div>

    <script type="module" src="main.js"></script>
  </body>
</html>
```

2. **JavaScript** (`main.js`):

```javascript theme={null}
import { CivicAuth } from "@civic/auth/vanillajs";

// Initialize auth directly with top-level await
const authClient = await CivicAuth.create({
  clientId: "YOUR_CLIENT_ID",
});

// Sign in
document.getElementById("loginButton").addEventListener("click", async () => {
  try {
    const { user } = await authClient.startAuthentication();
  } catch (error) {
    console.error("Authentication failed:", error);
  }
});

// Sign out
document.getElementById("logoutButton").addEventListener("click", async () => {
  await authClient?.logout();
});
```

That's it! Replace `YOUR_CLIENT_ID` with your actual client ID and you're done.

## Alternative: Backend Integration

If you prefer backend session management, you can configure the client to get login URLs from your Express backend. The magic is the `loginUrl` option:

```javascript theme={null}
import { CivicAuth } from "@civic/auth/vanillajs";

// Configure client to use your backend for login URLs
const authClient = await CivicAuth.create({
  loginUrl: "https://your-backend.com/auth/login-url", // The magic!
});

// Now authentication works through your backend
const { user } = await authClient.startAuthentication();
```

### Custom Backend Endpoints

When using backend integration, you can customize the API endpoints that the client calls on your backend:

```javascript theme={null}
import { CivicAuth } from "@civic/auth/vanillajs";

const authClient = await CivicAuth.create({
  loginUrl: "https://your-backend.com/auth/login-url",
  backendEndpoints: {
    refresh: "/api/v1/auth/refresh", // default: "/auth/refresh"
    logout: "/api/v1/auth/logout", // default: "/auth/logout"
    user: "/api/v1/auth/user", // default: "/auth/user"
  },
});
```

<Note>
  The `backendEndpoints` configuration is only used when `loginUrl` is provided. Each endpoint is optional - if not
  specified, the default will be used.
</Note>

### Configuration Options

| Field                    | Required | Default                          | Description                                                                 |
| ------------------------ | -------- | -------------------------------- | --------------------------------------------------------------------------- |
| `clientId`               | Yes      | -                                | Your Civic Auth client ID from [auth.civic.com](https://auth.civic.com)     |
| `targetContainerElement` | No       | -                                | DOM element where embedded iframe will be rendered                          |
| `redirectUrl`            | No       | Current URL                      | OAuth redirect URL after authentication                                     |
| `displayMode`            | No       | `modal`                          | How the auth UI is displayed: `embedded`, `modal`, `redirect`, or `new_tab` |
| `scopes`                 | No       | `['openid', 'profile', 'email']` | OAuth scopes to request                                                     |
| `loginUrl`               | No       | -                                | Backend URL for login redirect (enables backend integration)                |
| `backendEndpoints`       | No       | See below                        | Custom backend API endpoints (only used with `loginUrl`)                    |

#### Backend Endpoints Default Values

When using `loginUrl` for backend integration, the following default endpoints are used:

```javascript theme={null}
backendEndpoints: {
  refresh: "/auth/refresh",  // Token refresh endpoint
  logout: "/auth/logout",    // Logout endpoint
  user: "/auth/user"         // User info endpoint
}
```

### Display Modes

The `displayMode` option controls how the authentication UI is presented:

* **`embedded`** (default): The auth UI loads in an iframe within your specified container element
* **`modal`**: The auth UI opens in a modal overlay on top of your current page
* **`redirect`**: Full page navigation to the Civic auth server and back to your site
* **`new_tab`**: Opens auth flow in a new browser tab/popup window

### Logout

Logging out is very simple.

```javascript theme={null}
const logout = async () => {
  await authClient?.logout();
  // ...
};
```

**User object access:**

* Use `authClient.getCurrentUser()` to retrieve current user information before logout
* Use `authClient.isAuthenticated()` to check if user is currently logged in

## Troubleshooting

### Module Resolution Error

If you encounter an error like `Failed to resolve module specifier "@civic/auth/vanillajs"`, this is typically caused by a corrupted module cache or installation issue.

**Solution:**

```bash theme={null}
# Clear node_modules and package-lock.json, then reinstall
rm -rf node_modules package-lock.json
npm install
```

**For Vite users:**

```bash theme={null}
# Also clear Vite's cache
rm -rf node_modules package-lock.json .vite
npm install
```

This issue can occur when switching between different versions of the `@civic/auth` package or when the package installation is interrupted.

### Common Issues

* **CORS errors**: Ensure your redirect URL in the Civic Auth dashboard exactly matches your development server URL
* **Authentication not starting**: Verify your client ID is correct and your redirect URL is properly configured
* **Container element not found**: Make sure the target container element exists in the DOM before initializing Civic Auth

## API Reference

### CivicAuth Class

#### `startAuthentication()`

Initiates the authentication process.

**Returns:** Promise that resolves when authentication completes or rejects on error

#### `getCurrentUser()`

Retrieves the current authenticated user's information.

**Returns:** Promise that resolves to a user object or null if not authenticated

#### `isAuthenticated()`

Checks if a user is currently authenticated.

**Returns:** Promise that resolves to a boolean indicating authentication status

#### `logout()`

Logs out the user.

Returns a boolean or throws an error if unsuccessful
