The State of Docs Report 2025 is live! Dive in and see why docs matter more than ever:
Read the report
LogoLogo
ProductPricingLog inSign up
  • Documentation
  • Developers
  • Guides
  • Changelog
  • Help Center
  • Getting Started
    • GitBook Documentation
    • Quickstart
    • Importing content
    • GitHub & GitLab Sync
      • Enabling GitHub Sync
      • Enabling GitLab Sync
      • Content configuration
      • GitHub pull request preview
      • Commit messages & Autolink
      • Monorepos
      • Troubleshooting
  • Creating Content
    • Formatting your content
      • Inline content
      • Markdown
    • Content structure
      • Spaces
      • Pages
      • Collections
    • Blocks
      • Paragraphs
      • Headings
      • Unordered lists
      • Ordered lists
      • Task lists
      • Hints
      • Quotes
      • Code blocks
      • Files
      • Images
      • Embedded URLs
      • Tables
      • Cards
      • Tabs
      • Expandable
      • Stepper
      • Drawings
      • Math & TeX
      • Page links
    • Reusable content
    • Broken links
    • Searching content
      • Search & Quick find
      • GitBook AI
    • Writing with GitBook AI
    • Version control
  • API References
    • OpenAPI
      • Add an OpenAPI specification
      • Insert API reference in your docs
    • Guides
      • Structuring your API reference
      • Adding custom code samples
      • Managing API operations
      • Describing enums
      • Integrating with CI/CD
  • Extensions reference
  • Publishing Documentation
    • Publish a docs site
      • Public publishing
      • Private publishing with share links
    • Site structure
      • Content variants
      • Site sections
    • Site customization
      • Icons, colors, and themes
      • Layout and structure
      • Extra configuration
    • Set a custom domain
    • Setting a custom subdirectory
      • Configuring a subdirectory with Cloudflare
      • Configuring a subdirectory with Vercel
    • Site settings
    • Site insights
    • Site redirects
    • Visitor authentication
      • Enabling visitor authentication
      • Setting up Auth0
      • Setting up Azure AD
      • Setting up AWS Cognito
      • Setting up Okta
      • Setting up OIDC
      • Setting up a custom backend
    • Adaptive content
      • Enabling adaptive content
      • Adapting your content
      • Testing with segments
  • LLM-ready docs
  • Collaboration
    • Live edits
    • Change requests
    • PDF export
    • Inviting your team
    • Comments
    • Notifications
  • Integrations
    • Install and manage integrations
    • GitHub Copilot
  • Account management
    • Plans
      • Legacy pricing
      • Sponsored site plan
      • Non-profit plan
      • Billing policy
    • Subscription cancellations
    • Personal settings
    • Organization settings
    • Member management
      • Invite or remove members
      • Roles
      • Teams
      • Permissions and inheritance
    • SSO & SAML
      • SSO Members vs non-SSO
  • Resources
    • GitBook UI
    • Keyboard shortcuts
    • Glossary
Powered by GitBook
LogoLogo

Resources

  • Showcase
  • Enterprise
  • Status

Company

  • Careers
  • Blog
  • Community

Policies

  • Subprocessors
  • Terms of Service
On this page
  • Enable adaptive content
  • Set your adaptive schema
  • Ways to pass visitors's data to GitBook
  • Signed cookie method
  • Pass unsigned claims via query parameters
  • Visitor authentication method

Was this helpful?

Edit on GitHub
  1. Publishing Documentation
  2. Adaptive content

Enabling adaptive content

Choose an authentication method to pass user data to GitBook.

Last updated 4 days ago

Was this helpful?

To start customizing your documentation experience for your readers, you'll need to enable adaptive content and decide how your visitor data is passed to GitBook. This lets your site's content dynamically adapt based on who's viewing it.

Enable adaptive content

Before you’re able to pass user data to GitBook, you’ll need to configure your site to use adaptive content.

Head to your , and enable “Adaptive content” from your site’s audience settings. Once enabled, you’ll get a generated “Visitor token signing key”, which you’ll need in order to continue the adaptive content setup.

Set your adaptive schema

After enabling adaptive content, you’ll need to define a schema for the types of claims you expect GitBook to receive when a user visits your site.

The adaptive content schema should reflect how these claims are structured when sent to GitBook.

For example, if you expect a visitor to potentially be a beta user in your product, you would set an adaptive schema similar to:

{
  "type": "object",
  "properties": {
    "isBetaUser": {
      "type": "boolean",
      "description": "Whether the visitor is a Beta user.”
    },
  },
  "additionalProperties": false
}

If you intend to work with unsigned claims, you will need to declare the claims you are expecting in the schema under an “unsigned” prop alongside your signed claims.

{
  "type": "object",
  "properties": {
    "isBetaUser": {
      "type": "boolean",
      "description": "Whether the visitor is a Beta user.”
    },
    // Add unsigned claims
    "unsigned": {
      "type": "object",
      "description": "Unsigned claims of the site visitor.",
      "properties": {
        "language": {
          "type": "string",
          "description": "The language of the visitor",
          "enum": [
            "en",
            "fr",
            "it"
          ]
        }
      },
      "additionalProperties": false
    }
  }
  "additionalProperties": false
}

Next, you’ll need to decide how you want to pass your visitor data to GitBook.

Ways to pass visitors's data to GitBook

GitBook provides different ways to pass visitor data to adapt your site's content. Choose the option that best suits your needs:

Methods

Method
Use-cases
Ease of setup
Security
Format
Transport

Signed cookie gitbook-visitor-token

API test credentials, customer identification, etc

Require signing and a custom domain

JWT

Cookies

Public cookie gitbook-visitor

Feature flags

Easy to use

JSON

Cookies

Signed query parameter token

Require signing and a custom domain

JWT

URL

Query parameters gitbook_<prop>=

Easy to use

JSON

URL

Signed cookie method

To set this up, you'll need to adjust your application’s login flow to include the following steps:

1

Generate a JWT when users logs in to your application

Whenever a user logs in to your product, generate a JWT that contains selected attributes of your authenticated user's info.

2

Sign the JWT using the site's visitor signing key

Then, make sure to sign the JWT using the site's visitor signing key, which you can find in your site’s audience settings after enabling Adaptive Content.

3

Store the JWT in a wildcard session cookie

Finally you need to store the signed JWT containing your user's info into a wildcard session cookie under your product domain.

For example, if your application is served behind the app.acme.org domain, the cookie will need to be created under the .acme.org wildcard domain.

Here's what the code of your application login handler might look like after incorporating these steps:

import * as jose from 'jose';

import { Request, Response } from 'express';

import { getUserInfo } from '../services/user-info-service';
import { getFeatureFlags } from '../services/feature-flags-service';

const GITBOOK_VISITOR_SIGNING_KEY = process.env.GITBOOK_VISITOR_SIGNING_KEY;
const GITBOOK_VISITOR_COOKIE_NAME = 'gitbook-visitor-token';


export async function handleAppLoginRequest(req: Request, res: Response) {
   // Your business logic for handling the login request
   // For example, checking credentials and authenticating the user
   //
   // e,g:
   // const loggedInUser = await authenticateUser(req.body.username, req.body.password);

   // After authenticating the user, retrieve user information that you wish
   // to pass to GitBook from your database or user service.
   const userInfo = await getUserInfo(loggedInUser.id);
      
   // Build the JWT payload with the user's information
   const gitbookVisitorClaims = {
       firstName: userInfo.firstName,
       lastName: userInfo.lastName,
       isBetaUser: userInfo.isBetaUser
       products: userInfo.products.map((product) => product.name),
       featureFlags: await getFeatureFlags({userId: loggedInUser.id})
   }
   
   // Generate a signed JWT using the claims
   const gitbookVisitorJWT = await new jose.SignJWT(gitbookVisitorClaims)
     .setProtectedHeader({ alg: 'HS256' })
     .setIssuedAt()
     .setExpirationTime('2h') // abritary 2 hours expiration
     .sign(GITBOOK_VISITOR_SIGNING_KEY);
     
  // Include a `gitbook-visitor-token` cookie including the encoded JWT in your
  // login handler response
  res.cookie(GITBOOK_VISITOR_COOKIE_NAME, gitbookVisitorJWT, {
     httpOnly: true,
     secure: process.env.NODE_ENV === 'production',
     maxAge: 2 * 60 * 60 * 1000, // abritary 2 hours expiration
     domain: '.acme.org' //
  });
  
  // Rest of your login handler logic including redirecting the user to your app
  res.redirect('/'); // Example redirect
}

After successfully signing the cookie for a user when they log into your app, they will have associated data with them upon visiting your published GitBook site.

Following the example above, the data available for this user could look like:

{
   "visitor":{
      "claims":{
         "firstName": "John",
         "lastName": "Doe",
         "isBetaUser": true,
         "products":[
            "PRODUCT_A",
            "PRODUCT_C"
         ],
         "featureFlags":{
            "PRODUCT_V2_FEATURE": true
         }
      }
   }
}

Pass unsigned claims via query parameters

After setting up your schema to accept unsigned claims, you’ll be able to pass them through the URL of your published site.

https://docs.acme.org/?visitor.language=fr

Visitor authentication method

GitBook offers out-of-the box solutions to protect your docs. Integrations for Auth0, Okta, Azure AD, and AWS Cognito allow you install an integration to enforce a log-in screen before being able to access your published site.

Depending on which visitor authentication method you’re using, you’ll still need to configure a few more things depending on which integration you’re using in order to send the right data to GitBook.

Head to the relevant guide for full instructions on setting up adaptive content with visitor authentication.

This will also help you use autocomplete when configuring your claims in the .

: When you don't require full authentication for your docs but still want to use your user’s data to adapt your public site's content based on their information.

: When you need your site to be behind and want to customize the site's content based on your authenticated user’s information.

Properties can only be defined by the backend

Visitor can override the properties

Properties can only be defined by the backend

Visitor can override the properties

This approach only works if your site is served under a subdomain of your application domain. To set up a custom domain on your site follow the steps outlined .

When you don’t need your documentation to be fully behind authentication but still want to tailor its content for users logged into your application, you can store their user attributes as a in a cookie named gitbook-visitor-token tied to your product domain.

For instance, in the , we can pass the language claim to our published site when visiting this url:

in this section
JSON Web Token
Cookie method
authentication
Visitor authentication method
example above
✅
❌
✅
❌
condition editor
site’s settings
Enable adaptive content
Cover

Setting up Auth0

Configure Auth0 with visitor authentication and adaptive content.

Cover

Setting up Azure AD

Configure Azure AD with visitor authentication and adaptive content.

Cover

Setting up AWS Cognito

Configure AWS Cognito with visitor authentication and adaptive content.

Cover

Setting up Okta

Configure Okta with visitor authentication and adaptive content.

Cover

Setting up a custom backend

Configure a custom backend with visitor authentication and adaptive content.