{"ast":{"$$mdtype":"Tag","name":"article","attributes":{},"children":[{"$$mdtype":"Tag","name":"Heading","attributes":{"level":1,"id":"configure-dynamic-api-data-for-replay","__idx":0},"children":["Configure dynamic API data for Replay"]},{"$$mdtype":"Tag","name":"ConfigOptionRequirements","attributes":{"products":["Redoc","Revel","Realm"],"plans":["Pro","Enterprise","Enterprise+"]},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["You can dynamically configure request values for Replay by ejecting and customizing the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["use-configure-replay.ts"]}," file."," ","This lets you fetch configuration from external APIs at runtime, updating based on the current operation."," ","The ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["useConfigureReplay"]}," hook fetches fresh configuration when the Replay is opened or when the 'Reset request' button is clicked."," ","This way, you always get the latest configuration."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"before-you-begin","__idx":1},"children":["Before you begin"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Make sure you have the following:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["a basic understanding of TypeScript and React hooks"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["OpenAPI description files with examples"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["an external API endpoint to fetch configuration from"]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"eject-use-configure-replayts","__idx":2},"children":["Eject use-configure-replay.ts"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["To customize dynamic Replay values, first eject the configuration file:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"bash","header":{"controls":{"copy":{}}},"source":"npx @redocly/cli eject component ext/use-configure-replay.ts\n","lang":"bash"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["This command creates a local copy of ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["use-configure-replay.ts"]}," in your project's ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["@theme"]}," folder."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"implement-dynamic-configuration","__idx":3},"children":["Implement dynamic configuration"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["use-configure-replay.ts"]}," file exports a ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["useConfigureReplay"]}," hook that fetches request values dynamically."," ","The hook receives a context parameter with operation details."," ","It returns an object containing the configuration and a refresh function that can be used to manually reload the configuration."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Here are examples of how to implement dynamic Replay configuration:"]},{"$$mdtype":"Tag","name":"Tabs","attributes":{"size":"medium"},"children":[{"$$mdtype":"Tag","name":"TabItemFragment","attributes":{"label":"Global request values","disable":false},"children":[{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"typescript","data-title":"use-configure-replay.ts","header":{"title":"use-configure-replay.ts","controls":{"copy":{}}},"source":"import { useEffect, useState, useCallback } from 'react';\n\nimport type {\n  ConfigureRequestValues,\n  ConfigureServerRequestValues,\n} from '@redocly/theme/ext/configure';\nimport type { UserClaims, OpenAPIServer, OpenAPIInfo } from '@redocly/theme/core/types';\n\ntype ContextProps = {\n  operation: {\n    name: string;\n    path: string;\n    operationId: string;\n    href: string;\n    method: string;\n  };\n  info: OpenAPIInfo;\n  servers: OpenAPIServer[];\n  userClaims: UserClaims;\n};\n\nasync function getReplayConfiguration(\n  context: ContextProps,\n): Promise<ConfigureRequestValues | ConfigureServerRequestValues | null> {\n  try {\n    const response = await fetch(`/api/replay-config/${context.operation.operationId}`, {\n      method: 'GET',\n      headers: {\n        'Content-Type': 'application/json',\n      },\n    });\n\n    if (!response.ok) {\n      throw new Error(`HTTP error! status: ${response.status}`);\n    }\n\n    const { token } = await response.json();\n  \n    // Return global request values that apply to all servers\n    return {\n      security: {\n        default: {\n          token: {\n            access_token: token\n          }\n        }\n      }\n    };\n  } catch (error) {\n    console.warn('Failed to fetch replay configuration:', error);\n    throw error;\n  }\n}\n\nexport function useConfigureReplay(context: ContextProps, isOpened: boolean) {\n  const [config, setConfig] = useState<\n    ConfigureRequestValues | ConfigureServerRequestValues | null\n  >();\n\n  const refresh = useCallback(async () => {\n    try {\n      const result = await getReplayConfiguration(context);\n      setConfig(result);\n    } catch (error) {\n      console.warn(\n        'Failed to configure replay for operation:',\n        context.operation.operationId,\n        error,\n      );\n    }\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, []);\n\n  useEffect(() => {\n    if (isOpened) {\n      refresh();\n    }\n  }, [isOpened, refresh]);\n\n  return { config, refresh };\n}\n","lang":"typescript"},"children":[]}]},{"$$mdtype":"Tag","name":"TabItemFragment","attributes":{"label":"Server-specific request values","disable":false},"children":[{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"typescript","data-title":"use-configure-replay.ts","header":{"title":"use-configure-replay.ts","controls":{"copy":{}}},"source":"import { useEffect, useState, useCallback } from 'react';\n\nimport type {\n  ConfigureRequestValues,\n  ConfigureServerRequestValues,\n} from '@redocly/theme/ext/configure';\nimport type { UserClaims, OpenAPIServer, OpenAPIInfo } from '@redocly/theme/core/types';\n\ntype ContextProps = {\n  operation: {\n    name: string;\n    path: string;\n    operationId: string;\n    href: string;\n    method: string;\n  };\n  info: OpenAPIInfo;\n  servers: OpenAPIServer[];\n  userClaims: UserClaims;\n};\n\nasync function getReplayConfiguration(\n  context: ContextProps,\n): Promise<ConfigureRequestValues | ConfigureServerRequestValues | null> {\n  try {\n    const response = await fetch(`/api/replay-config/${context.operation.operationId}`, {\n      method: 'GET',\n      headers: {\n        'Content-Type': 'application/json',\n      },\n    });\n\n    if (!response.ok) {\n      throw new Error(`HTTP error! status: ${response.status}`);\n    }\n\n    const { token, host } = await response.json();\n  \n    // Return server-specific request values\n    return {\n      'https://{api_host}/v1.1': {\n        security: {\n          default: {\n            token: {\n              access_token: token\n            }\n          }\n        },\n        serverVariables: {\n          api_host: host\n        }\n      }\n    };\n  } catch (error) {\n    console.warn('Failed to fetch replay configuration:', error);\n    throw error;\n  }\n}\n\nexport function useConfigureReplay(context: ContextProps, isOpened: boolean) {\n  const [config, setConfig] = useState<\n    ConfigureRequestValues | ConfigureServerRequestValues | null\n  >();\n\n  const refresh = useCallback(async () => {\n    try {\n      const result = await getReplayConfiguration(context);\n      setConfig(result);\n    } catch (error) {\n      console.warn(\n        'Failed to configure replay for operation:',\n        context.operation.operationId,\n        error,\n      );\n    }\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, []);\n\n  useEffect(() => {\n    if (isOpened) {\n      refresh();\n    }\n  }, [isOpened, refresh]);\n\n  return { config, refresh };\n}\n","lang":"typescript"},"children":[]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"configure-security-credentials","__idx":4},"children":["Configure security credentials"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Here's an example showing how to fetch security credentials from an API and apply them to different security schemes in your OpenAPI description:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"yaml","data-title":"openapi.yaml","header":{"title":"openapi.yaml","controls":{"copy":{}}},"source":"openapi: 3.0.0\ninfo:\n  title: Museum API\n  version: 1.0.0\ncomponents:\n  securitySchemes:\n    MuseumPlaceholderAuth:\n      type: http\n      scheme: basic\n    BearerAuth:\n      type: http\n      scheme: bearer\n","lang":"yaml"},"children":[]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"typescript","data-title":"use-configure-replay.ts","header":{"title":"use-configure-replay.ts","controls":{"copy":{}}},"source":"import { useEffect, useState, useCallback } from 'react';\n\nimport type {\n  ConfigureRequestValues,\n  ConfigureServerRequestValues,\n} from '@redocly/theme/ext/configure';\nimport type { UserClaims, OpenAPIServer, OpenAPIInfo } from '@redocly/theme/core/types';\n\ntype ContextProps = {\n  operation: {\n    name: string;\n    path: string;\n    operationId: string;\n    href: string;\n    method: string;\n  };\n  info: OpenAPIInfo;\n  servers: OpenAPIServer[];\n  userClaims: UserClaims;\n};\n\nasync function getReplayConfiguration(\n  context: ContextProps,\n): Promise<ConfigureRequestValues | ConfigureServerRequestValues | null> {\n  try {\n    const response = await fetch(`/api/replay-config/${context.operation.operationId}`, {\n      method: 'GET',\n      headers: {\n        'Content-Type': 'application/json',\n      },\n    });\n\n    if (!response.ok) {\n      throw new Error(`HTTP error! status: ${response.status}`);\n    }\n\n    const { token, username, password } = await response.json();\n  \n    return {\n      security: {\n        default: {\n          token: {\n            access_token: token\n          }\n        },\n        MuseumPlaceholderAuth: {\n          username,\n          password\n        }\n      }\n    };\n  } catch (error) {\n    console.warn('Failed to fetch replay configuration:', error);\n    throw error;\n  }\n}\n\nexport function useConfigureReplay(context: ContextProps, isOpened: boolean) {\n  const [config, setConfig] = useState<\n    ConfigureRequestValues | ConfigureServerRequestValues | null\n  >();\n\n  const refresh = useCallback(async () => {\n    try {\n      const result = await getReplayConfiguration(context);\n      setConfig(result);\n    } catch (error) {\n      console.warn(\n        'Failed to configure replay for operation:',\n        context.operation.operationId,\n        error,\n      );\n    }\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, []);\n\n  useEffect(() => {\n    if (isOpened) {\n      refresh();\n    }\n  }, [isOpened, refresh]);\n\n  return { config, refresh };\n}\n","lang":"typescript"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["In this example:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["BearerAuth"]}," uses the Bearer token from ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["default"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["MuseumPlaceholderAuth"]}," uses the specific Basic Auth credentials"]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"share-values-across-operations-with-envvariables","__idx":5},"children":["Share values across operations with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["envVariables"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["envVariables"]}," lets users enter a value once and have Replay reuse it in every operation that needs it."," ","That holds even when the same value is a header on one endpoint and a path parameter on another."," ","Each entry in ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["envVariables"]}," is matched by name against every input the current operation exposes (path, query, header, cookie, and security inputs)."," ","You don't need any per-operation configuration."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["For example:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"typescript","header":{"controls":{"copy":{}}},"source":"return {\n  envVariables: {\n    'X-Tenant-Id': 'acme',\n    'billerId': '42',\n  },\n};\n","lang":"typescript"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["With a single config like this, the same ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["billerId"]}," entry can apply to a path parameter in one operation and a header in another."," ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["X-Tenant-Id"]}," is picked up wherever it appears."," ","Entries the current operation doesn't declare are silently ignored."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"example-shared-variables-form-backed-by-localstorage","__idx":6},"children":["Example: shared variables form backed by ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["localStorage"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["A common pattern is to collect these values from the user in a ",{"$$mdtype":"Tag","name":"Link","attributes":{"href":"/docs/realm/customization/create-react-page"},"children":["React page"]},", persist them in ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["localStorage"]},", and read them back in ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["useConfigureReplay"]},"."]},{"$$mdtype":"Tag","name":"Admonition","attributes":{"type":"warning","name":"Avoid persisting secrets"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["localStorage"]}," persists indefinitely and is readable by any script on the page, so it's vulnerable to XSS."," ","For sensitive credentials, prefer ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sessionStorage"]},", which is cleared when the session ends."]}]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"tsx","data-title":"api-variables.page.tsx","header":{"title":"api-variables.page.tsx","controls":{"copy":{}}},"source":"import React, { useEffect, useState } from 'react';\n\nconst STORAGE_KEY = 'replay_shared_variables';\n\nfunction readVariables() {\n  if (typeof window === 'undefined') return {};\n  const raw = localStorage.getItem(STORAGE_KEY);\n  return raw ? JSON.parse(raw) : {};\n}\n\nexport default function ApiVariablesPage() {\n  const [variables, setVariables] = useState<Record<string, string>>({});\n\n  useEffect(() => {\n    setVariables(readVariables());\n  }, []);\n\n  const updateVariable = (name: string, value: string) => {\n    const next = { ...variables, [name]: value };\n    setVariables(next);\n    localStorage.setItem(STORAGE_KEY, JSON.stringify(next));\n  };\n\n  return (\n    <div style={{ padding: 40, maxWidth: 480 }}>\n      <h1>API variables</h1>\n      <p>Enter these values once. They are reused by every operation in the catalog.</p>\n\n      <label>X-Tenant-Id\n        <input\n          value={variables['X-Tenant-Id'] ?? ''}\n          onChange={(e) => updateVariable('X-Tenant-Id', e.target.value)}\n        />\n      </label>\n      <label>Biller ID\n        <input\n          value={variables.billerId ?? ''}\n          onChange={(e) => updateVariable('billerId', e.target.value)}\n        />\n      </label>\n    </div>\n  );\n}\n","lang":"tsx"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Then, in the ejected ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["use-configure-replay.ts"]},", swap the body of ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["getReplayConfiguration"]}," to read from ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["localStorage"]}," and return the values as ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["envVariables"]},":"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"typescript","data-title":"use-configure-replay.ts (excerpt)","header":{"title":"use-configure-replay.ts (excerpt)","controls":{"copy":{}}},"source":"const STORAGE_KEY = 'replay_shared_variables';\n\nasync function getReplayConfiguration(\n  context: ContextProps,\n): Promise<ConfigureRequestValues | ConfigureServerRequestValues | null> {\n  if (typeof window === 'undefined') return null;\n  const raw = localStorage.getItem(STORAGE_KEY);\n\n  return { envVariables: raw ? JSON.parse(raw) : {} };\n}\n","lang":"typescript"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The rest of the hook (state, ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["refresh"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["useEffect"]},") stays exactly as in the ",{"$$mdtype":"Tag","name":"Link","attributes":{"href":"#implement-dynamic-configuration"},"children":["examples above"]},"."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"override-behavior","__idx":7},"children":["Override behavior"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["A few things worth knowing:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["An ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["empty string"]}," is treated as \"clear this value\"."," ","It is useful when a value in your app gets reset and you want Replay to forget the old one too."," ","Omit the key entirely if you want the persisted value to stay."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["A field-specific entry (such as ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["security.default.token.access_token"]}," or ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["headers['X-Tenant-Id']"]},") wins over a same-named entry in ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["envVariables"]},"."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"empty-input-hints--inputhints-","__idx":8},"children":["Empty input hints (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["inputHints"]},")"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["When an input is defined but has no value (for example ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["${inputs.bearerAuth_token}"]}," in Try it), Replay shows a tooltip."," ","Use ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["inputHints"]}," in the object returned from ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["getReplayConfiguration"]}," to customize that message for each input name."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["You can add titles, descriptions, and optional action buttons to empty-input tooltips."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Input names match environment variable names generated from your OpenAPI security schemes (for example ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["bearerAuth_token"]}," for a scheme id ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["bearerAuth"]},")."," ","Use the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["\"default\""]}," key as a fallback when no input-specific hint exists."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"root-level-and-server-level-hints","__idx":9},"children":["Root-level and server-level hints"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["inputHints"]}," can be set at the root level (a shared default that applies to every server)."," ","It can also be nested under a server entry when you return ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["ConfigureServerRequestValues"]},"."," ","For the other request values (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["headers"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["security"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["envVariables"]},", and so on), a server-keyed entry replaces the root value for that server."," ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["inputHints"]}," from both levels are combined instead — the server level takes priority and the root level fills in the rest."," ","Resolution for a given input follows this precedence:"]},{"$$mdtype":"Tag","name":"ol","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["The server-level hint for the active server (by input name, then its ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["\"default\""]},")."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["The root-level hint (by input name, then its ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["\"default\""]},")."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Replay's standard \"undefined input\" message when neither level resolves a hint."]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["This lets you keep a shared set of root-level hints and override individual inputs per server."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"typescript","data-title":"use-configure-replay.ts (excerpt)","header":{"title":"use-configure-replay.ts (excerpt)","controls":{"copy":{}}},"source":"return {\n  // Root-level hints apply to every server.\n  inputHints: {\n    bearerAuth_token: { title: 'Sign in to auto-fill', text: 'Added automatically after sign-in.' },\n    default: { title: 'Missing input value', text: 'Set a value in the environment.' },\n  },\n  // Server-level values, with an optional per-server hint override.\n  'https://api.example.com/v2': {\n    security: { default: { token: { access_token: '' } } },\n    inputHints: {\n      bearerAuth_token: { title: 'Production token', text: 'Use your production credentials.' },\n    },\n  },\n};\n","lang":"typescript"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"actions-behavior","__idx":10},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["actions"]}," behavior"]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"actions"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["actions"]}]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Tooltip footer"},"children":["Tooltip footer"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["omitted or ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["undefined"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Custom title and text, then the default ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Set value"]}," button"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["[]"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Custom title and text only (no buttons)"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["[{ label, action }, ...]"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Custom title and text, then your buttons (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["action"]}," runs on click)"]}]}]}]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["action"]}," must be a function returned from ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["getReplayConfiguration"]}," in your theme (not from a JSON API response)."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"example-for-unauthenticated-users","__idx":11},"children":["Example for unauthenticated users"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"typescript","data-title":"use-configure-replay.ts (excerpt)","header":{"title":"use-configure-replay.ts (excerpt)","controls":{"copy":{}}},"source":"if (!context.userClaims?.email) {\n  return {\n    inputHints: {\n      bearerAuth_token: {\n        title: 'Sign in to auto-fill',\n        text: 'This authorization token is added automatically after you sign in.',\n        actions: [\n          {\n            label: 'Sign in',\n            action: () => {\n              window.location.assign('/login');\n            },\n          },\n        ],\n      },\n    },\n    security: {\n      default: {\n        token: {\n          access_token: '',\n        },\n      },\n    },\n  };\n}\n","lang":"typescript"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["When the user is signed in, return ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["security"]}," / ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["envVariables"]}," with real values and omit ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["inputHints"]},"."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"use-cases-for-dynamic-replay-configuration","__idx":12},"children":["Use cases for dynamic Replay configuration"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Dynamic Replay configuration is useful for:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Token management"]},": fetching fresh access tokens from your authentication service"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["User-specific data"]},": including user context in requests"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Environment-specific values"]},": retrieving configuration based on the current environment"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Server variable configuration"]},": dynamically setting server variables for URLs"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["External service integration"]},": fetching configuration from third-party services"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Empty input messaging"]},": explaining why credentials are empty and linking to sign-in or docs via ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["inputHints"]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"context-parameter","__idx":13},"children":["Context parameter"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The context parameter includes:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["userClaims"]},": information about the authenticated user and their original IdP tokens",{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["email"]},": user email"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["name"]},": user name"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["federatedAccessToken"]},": access token of the original identity provider."," ","Requires ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["REDOCLY_OAUTH_USE_INTROSPECT"]}," to be set to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["true"]}," in the environment variables."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["federatedIdToken"]},": ID token of the original identity provider."," ","Requires ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["REDOCLY_OAUTH_USE_INTROSPECT"]}," to be set to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["true"]}," in the environment variables."]}]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["operation"]},": details about the current API operation",{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["name"]},": operation name"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["path"]},": API path"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["operationId"]},": operation ID"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["href"]},": operation URL"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["method"]},": HTTP method"]}]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["info"]},": OpenAPI info object"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["servers"]},": server information from the OpenAPI description"]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"return-types","__idx":14},"children":["Return types"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["useConfigureReplay"]}," hook returns an object with:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["config"]},": the request values configuration, which can be:",{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["ConfigureRequestValues"]},": set global request values that apply to all servers (including optional ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["inputHints"]},")"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["ConfigureServerRequestValues"]},": set different request values per server URL (each server entry may include ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["inputHints"]},")"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["null"]},": when configuration cannot be fetched or an error occurs"]}]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["refresh"]},": a function to manually refresh the configuration when called"]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"resources","__idx":15},"children":["Resources"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":[{"$$mdtype":"Tag","name":"Link","attributes":{"href":"/docs/realm/customization/configure-request-values"},"children":["Configure request values"]}]}," - Set static request values for headers, parameters, and security details in your OpenAPI descriptions"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":[{"$$mdtype":"Tag","name":"Link","attributes":{"href":"/docs/realm/customization/eject-components"},"children":["Eject components"]}]}," - Learn to eject and customize built-in components for advanced request value handling and UI modifications"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":[{"$$mdtype":"Tag","name":"Link","attributes":{"href":"/docs/realm/customization"},"children":["Extend with code"]}]}," - Discover customizable components and customization options for your project"]}]}]},"frontmatter":{"products":["Redoc","Revel","Realm"],"plans":["Pro","Enterprise","Enterprise+"]},"tagList":["admonition","configOptionRequirements","tab","table","tabs"],"title":"Configure dynamic API data for Replay","lastModified":"2026-10-01T23:00:57.000Z"}