--- url: /plugins/reference/sdks/backend.md --- # @caido/sdk-backend This is the reference for the backend SDK used by backend plugins. [SDK](#events) is the main interface that provides access to various services and functionalities. ## SDK ### SDK The SDK object available to all scripts. #### Type Parameters | Type Parameter | Default type | | ------ | ------ | | `API` | `object` | | `Events` | `object` | #### Properties ##### api > **api**: [`APISDK`](api.md#apisdk)<`API`, `Events`> The SDK for the API RPC service. ##### console > **console**: [`Console`](other.md#console) The console. This is currently the same as the global `console`. ##### env > **env**: [`EnvironmentSDK`](environment.md#environmentsdk) The SDK for the Environment service. ##### events > **events**: [`EventsSDK`](events.md#eventssdk)<`API`, `Events`> The SDK for the Events service. ##### findings > **findings**: [`FindingsSDK`](findings.md#findingssdk) The SDK for the Findings service. ##### graphql > **graphql**: [`GraphQLSDK`](graphql.md#graphqlsdk) The SDK for the GraphQL service. ##### hostedFile > **hostedFile**: [`HostedFileSDK`](hostedfile.md#hostedfilesdk) The SDK for the HostedFile service. ##### meta > **meta**: [`MetaSDK`](meta.md#metasdk) The SDK for metadata information about the plugin. ##### net > **net**: [`NetSDK`](net.md#netsdk) The SDK for the Net service. ##### projects > **projects**: [`ProjectsSDK`](projects.md#projectssdk) The SDK for the Projects service. ##### replay > **replay**: [`ReplaySDK`](replay.md#replaysdk) The SDK for the Replay service. ##### requests > **requests**: [`RequestsSDK`](requests.md#requestssdk) The SDK for the Requests service. ##### runtime > **runtime**: [`RuntimeSDK`](runtime.md#runtimesdk) The SDK for the runtime information. ##### scope > **scope**: [`ScopeSDK`](scope.md#scopesdk) The SDK for the Scope service. ## API Reference * [Meta](meta.md) * [API](api.md) * [Events](events.md) * [Requests](requests.md) * [Findings](findings.md) * [Replay](replay.md) * [Projects](projects.md) * [Shared](shared.md) * [Environment](environment.md) * [GraphQL](graphql.md) * [HostedFile](hostedfile.md) * [Net](net.md) * [Other](other.md) * [Runtime](runtime.md) * [Scope](scope.md) --- --- url: /plugins/reference/sdks/frontend.md --- # @caido/sdk-frontend This is the reference for the frontend SDK used by frontend plugins. [Caido](#caido-t-e) is the main interface that provides access to various services and functionalities. ## SDK ### Caido > **Caido**<`T`, `E`> = `object` Utilities for frontend plugins. #### Type Parameters | Type Parameter | Default type | | ------ | ------ | | `T` *extends* [`BackendEndpoints`](backend.md#backendendpoints) | `Record`<`string`, `never`> | | `E` *extends* [`BackendEvents`](backend.md#backendevents) | `Record`<`string`, `never`> | #### Properties ##### ai > **ai**: [`AiSDK`](ai.md#aisdk) Utilities to interact with AI. ##### assets > **assets**: [`AssetsSDK`](files.md#assetssdk) Utilities to interact with the plugin's static assets. ##### automate > **automate**: [`AutomateSDK`](automate.md#automatesdk) Utilities to interact with the Automate page. ##### backend > **backend**: [`BackendSDK`](backend.md#backendsdk)<`T`, `E`> Utilities to interact with the backend plugin. ##### commandPalette > **commandPalette**: [`CommandPaletteSDK`](command-palette.md#commandpalettesdk) Utilities to interact with the command palette. ##### commands > **commands**: [`CommandsSDK`](commands.md#commandssdk) Utilities to interact with commands ##### env > **env**: [`EnvironmentSDK`](environment.md#environmentsdk) Utilities to interact with the environment. ##### files > **files**: [`FilesSDK`](files.md#filessdk) Utilities to interact with the Files page. ##### filters > **filters**: [`FiltersSDK`](filters.md#filterssdk) Utilities to interact with Filters page. ##### findings > **findings**: [`FindingsSDK`](findings.md#findingssdk) Utilities to interact with findings ##### footer > **footer**: [`FooterSDK`](footer.md#footersdk) Utilities to interact with the footer. ##### graphql > **graphql**: `GraphqlSDK` Utilities to interact with the GraphQL API. ##### httpHistory > **httpHistory**: [`HTTPHistorySDK`](http-history.md#httphistorysdk) Utilities to interact with the HTTP History page. ##### intercept > **intercept**: [`InterceptSDK`](intercept.md#interceptsdk) Utilities to interact with the Intercept page. ##### log > **log**: [`LogSDK`](log.md#logsdk) Utilities for logging messages to the console. ##### matchReplace > **matchReplace**: [`MatchReplaceSDK`](match-and-replace.md#matchreplacesdk) Utilities to interact with Match and Replace page. ##### menu > **menu**: [`MenuSDK`](menu.md#menusdk) Utilities to insert menu items and context-menus throughout the UI. ##### navigation > **navigation**: [`NavigationSDK`](navigation.md#navigationsdk) Utilities to interact with navigation. ##### projects > **projects**: [`ProjectsSDK`](projects.md#projectssdk) Utilities to interact with projects. ##### replay > **replay**: [`ReplaySDK`](replay.md#replaysdk) Utilities to interact with the Replay page. ##### runtime > **runtime**: [`RuntimeSDK`](runtime.md#runtimesdk) Utilities to interact with the runtime. ##### scopes > **scopes**: [`ScopesSDK`](scopes.md#scopessdk) Utilities to interact with scopes ##### search > **search**: [`SearchSDK`](search.md#searchsdk) Utilities to interact with the Search page. ##### settings > **settings**: [`SettingsSDK`](settings.md#settingssdk) Utilities to interact with the settings page. ##### shortcuts > **shortcuts**: [`ShortcutsSDK`](shortcuts.md#shortcutssdk) Utilities to interact with shortcuts. ##### sidebar > **sidebar**: [`SidebarSDK`](sidebar.md#sidebarsdk) Utilities to interact with the sidebar. ##### sitemap > **sitemap**: [`SitemapSDK`](sitemap.md#sitemapsdk) Utilities to interact with the Sitemap page. ##### storage > **storage**: [`StorageSDK`](storage.md#storagesdk) Utilities to interact with frontend-plugin storage. ##### ui > **ui**: [`UISDK`](ui.md#uisdk) Utilities to create UI components. ##### window > **window**: [`WindowSDK`](window.md#windowsdk) Utilities to interact with the active page. ##### workflows > **workflows**: [`WorkflowSDK`](workflows.md#workflowsdk) Utilities to interact with workflows. ## API Reference * [Backend](backend.md) * [UI](ui.md) * [Scopes](scopes.md) * [Findings](findings.md) * [Commands](commands.md) * [Menu](menu.md) * [Navigation](navigation.md) * [Window](window.md) * [Storage](storage.md) * [Shortcuts](shortcuts.md) * [Command Palette](command-palette.md) * [Sidebar](sidebar.md) * [Replay](replay.md) * [HTTP History](http-history.md) * [Search](search.md) * [Files](files.md) * [AI](ai.md) * [Assistant](assistant.md) * [Automate](automate.md) * [Backups](backups.md) * [Certificate](certificate.md) * [Editor](editor.md) * [Environment](environment.md) * [Exports](exports.md) * [Filter](filter.md) * [Filters](filters.md) * [Footer](footer.md) * [Intercept](intercept.md) * [JSON](json.md) * [Log](log.md) * [Match and Replace](match-and-replace.md) * [Other](other.md) * [Projects](projects.md) * [Request](request.md) * [Response](response.md) * [Runtime](runtime.md) * [Settings](settings.md) * [Sitemap](sitemap.md) * [Slots](slots.md) * [Utils](utils.md) * [Websockets](websockets.md) * [Workflows](workflows.md) --- --- url: /plugins/reference/sdks/workflow.md --- # @caido/sdk-workflow This is the reference for the workflow SDK used by JS Nodes. [SDK](#sdk) is the main interface that provides access to various services and functionalities. ## SDK ### SDK > **SDK** = `object` The SDK object available to all scripts. #### Properties ##### console > **console**: [`Console`](other.md#console) The console for logging. This is currently the same as the global `console`. ##### env > **env**: [`EnvironmentSDK`](environment.md#environmentsdk) The SDK for the Environment service. ##### findings > **findings**: [`FindingsSDK`](findings.md#findingssdk) The SDK for the Findings service. ##### graphql > **graphql**: [`GraphQLSDK`](graphql.md#graphqlsdk) The SDK for the GraphQL service. ##### hostedFile > **hostedFile**: [`HostedFileSDK`](hostedfile.md#hostedfilesdk) The SDK for the HostedFile service. ##### net > **net**: [`NetSDK`](net.md#netsdk) The SDK for the Net service. ##### projects > **projects**: [`ProjectsSDK`](projects.md#projectssdk) The SDK for the Projects service. ##### replay > **replay**: [`ReplaySDK`](replay.md#replaysdk) The SDK for the Replay service. ##### requests > **requests**: [`RequestsSDK`](requests.md#requestssdk) The SDK for the Requests service. ##### runtime > **runtime**: [`RuntimeSDK`](runtime.md#runtimesdk) The SDK for the runtime information. ##### scope > **scope**: [`ScopeSDK`](scope.md#scopesdk) The SDK for the Scope service. #### Methods ##### asString() > **asString**(`array`: [`Bytes`](shared.md#bytes)): `string` Converts bytes to a string. Unprintable characters will be replaced with `�`. ###### Parameters | Parameter | Type | | ------ | ------ | | `array` | [`Bytes`](shared.md#bytes) | ###### Returns `string` ###### Example ```js export function run(input, sdk) { let parsed = sdk.asString(input); sdk.console.log(parsed); return parsed; } ``` ## API Reference * [Data](data.md) * [Requests](requests.md) * [Findings](findings.md) * [Replay](replay.md) * [Projects](projects.md) * [Shared](shared.md) * [Environment](environment.md) * [GraphQL](graphql.md) * [HostedFile](hostedfile.md) * [Net](net.md) * [Other](other.md) * [Runtime](runtime.md) * [Scope](scope.md) --- --- url: /plugins/guides/assets.md --- # Access Static Assets Static assets are files bundled with your plugin that can be accessed at runtime. You can load configuration files, images, templates, data files, and other resources from the assets folder. ## Getting an Asset To get a file from the assets folder: ```ts const asset = await sdk.assets.get("path/to/file.txt"); ``` The path is relative to your plugin's assets directory. ## Converting Assets to Different Formats Once you have an asset, you can convert it to different formats: ### Converting to String ```ts const content = await asset.asString(); ``` ### Converting to JSON ```ts const data = await asset.asJson(); ``` ### Converting to ArrayBuffer ```ts const buffer = await asset.asArrayBuffer(); ``` ### Converting to ReadableStream ```ts const stream = asset.asReadableStream(); ``` ::: tip Use `asReadableStream()` for large files to process them in chunks and avoid loading the entire file into memory. ::: ## Asset Path Configuration Assets are configured in your `caido.config.ts`: ```ts export default defineConfig({ frontend: { assets: ["./assets/**/*"], }, }); ``` ::: warning Assets are bundled with your plugin, so large files will increase the plugin size. Consider loading external resources at runtime for very large files. ::: ## Examples ### Loading Configuration This example loads a JSON configuration file from assets and parses it into a typed TypeScript object. It demonstrates error handling and logging for configuration loading operations. ```ts import type { Caido } from "@caido/sdk-frontend"; export type CaidoSDK = Caido; interface PluginConfig { apiKey: string; endpoint: string; timeout: number; } const loadConfig = async (sdk: CaidoSDK): Promise => { const asset = await sdk.assets.get("config.json"); const config = await asset.asJson(); return config; }; export const init = async (sdk: CaidoSDK) => { try { const config = await loadConfig(sdk); sdk.log.info("Loaded config:", config); // Use configuration } catch (error) { sdk.log.error("Failed to load config:", error); } }; ``` ### Loading Multiple Assets This example demonstrates loading multiple assets in parallel using Promise.all. It loads a JSON config file, a text template, and a data JSON file simultaneously, converting each to its appropriate format. ```ts import type { Caido } from "@caido/sdk-frontend"; export type CaidoSDK = Caido; const loadAssets = async (sdk: CaidoSDK) => { const [config, template, data] = await Promise.all([ sdk.assets.get("config.json").then((a) => a.asJson()), sdk.assets.get("template.txt").then((a) => a.asString()), sdk.assets.get("data.json").then((a) => a.asJson()), ]); return { config, template, data }; }; export const init = async (sdk: CaidoSDK) => { try { const assets = await loadAssets(sdk); sdk.log.info("Loaded all assets:", assets); } catch (error) { sdk.log.error("Failed to load assets:", error); } }; ``` --- --- url: /plugins/guides/files.md --- # Add Files To include additional files in your Caido plugins, you can add the `assets` property key to either the frontend or backend component objects in the `caido.config.ts` file. The key value is an array that stores the locations of any files accessible to the plugin. In this guide we'll cover how to add a file to a plugin named `myfile.txt`. ## Shared Steps In the root directory of your plugin package, create a new directory named `assets`. Within this directory, create the `myfile.txt` file, write content to it, and save it. The file can now be referenced with: ```ts assets : ["./assets/myfile.txt"] ``` ::: tip TIPS Glob syntax (`*`) is supported to reference multiple files: * `/path/*.txt`: Will include all `.txt` files in the path directory. * `/**/file.txt`: Will include any `file.txt` within any directory. Files and directories are included differently: * For a file, it will copy it at the root of the output assets directory. * For a directory, it will copy it recursively in the output assets directory. ::: ::: info The `assets` key can also be added to a plugin's `manifest.json` file. However, multiple locations can not be defined with this method. ::: ## Adding Files to the Frontend Component Open the `caido.config.ts` file and add the property to the `frontend` component object: ### /packages/frontend/src/index.ts To read the file, the `sdk.assets.get()` method can be called. ```ts const file = await sdk.assets.get("myfile.txt"); ``` ::: tip To view the entire frontend script, expand the following: ```ts import "./styles/index.css"; import type { FrontendSDK } from "./types"; // Note that the init function is async to account for fetching the files. export const init = async (sdk: FrontendSDK) => { const root = document.createElement("div"); Object.assign(root.style, { height: "100%", width: "100%", }); root.id = `plugin--frontend-vanilla`; const parent = document.createElement("div"); parent.classList.add("h-full", "flex", "justify-center", "items-center"); const container = document.createElement("div"); container.classList.add("flex", "flex-col", "gap-1", "p-4"); const file = await sdk.assets.get("myfile.txt"); // For large files or to process in chunks, use file.asReadableStream() instead. const content = await file.asString(); container.textContent = content; parent.appendChild(container); root.appendChild(parent); sdk.navigation.addPage("/view-file-plugin", { body: root, }); sdk.sidebar.registerItem("View File Plugin", "/view-file-plugin"); }; ``` ## Adding Files to the Backend Component Open the `caido.config.ts` file and add the property to the `backend` component object: ### /packages/backend/src/index.ts By [creating a custom backend function](./rpc.md) to read the file, we can later call it from the frontend: ```ts import type { DefineAPI, SDK } from "caido:plugin"; import { readFile } from 'fs/promises'; import path from "path"; const readMyFile = async (sdk: SDK) => { try { const filePath = path.join(sdk.meta.assetsPath(), "myfile.txt"); const contents = await readFile(filePath, { encoding: 'utf8' }); sdk.console.log(contents); return contents; } catch (err: any) { sdk.console.error(err.message); throw err; } }; export type API = DefineAPI<{ readMyFile: typeof readMyFile; }>; export function init(sdk: SDK) { sdk.api.register("readMyFile", readMyFile); } ``` ::: tip To view the entire frontend script, expand the following: ```ts import "./styles/index.css"; import type { FrontendSDK } from "./types"; export const init = async (sdk: FrontendSDK) => { const root = document.createElement("div"); Object.assign(root.style, { height: "100%", width: "100%", }); root.id = `plugin--frontend-vanilla`; const parent = document.createElement("div"); parent.classList.add("h-full", "flex", "justify-center", "items-center"); const container = document.createElement("div"); container.classList.add("flex", "flex-col", "gap-1", "p-4"); try { // Call the backend readMyFile() function to read myfile.txt. const content = await sdk.backend.readMyFile(); container.textContent = content; } catch (error: any) { container.textContent = `Error reading file: ${error.message}`; } parent.appendChild(container); root.appendChild(parent); sdk.navigation.addPage("/view-file-plugin", { body: root, }); sdk.sidebar.registerItem("View File Plugin", "/view-file-plugin"); }; ``` ## The Result ## Listening to File Events You can listen for events when hosted files are uploaded, updated, or deleted: ### Listening for File Uploads ```ts const handle = sdk.files.onUploadedHostedFile((file) => { sdk.log.info(`File uploaded: ${file.name} (${file.size} bytes)`); sdk.window.showToast(`File "${file.name}" uploaded`, { variant: "success" }); }); // Later, stop listening handle.stop(); ``` ### Listening for File Updates ```ts const handle = sdk.files.onUpdatedHostedFile((file) => { sdk.log.info(`File updated: ${file.name}`); sdk.window.showToast(`File "${file.name}" updated`, { variant: "info" }); }); // Later, stop listening handle.stop(); ``` ### Listening for File Deletions ```ts const handle = sdk.files.onDeletedHostedFile((fileId) => { sdk.log.info(`File deleted: ${fileId}`); sdk.window.showToast("File deleted", { variant: "info" }); }); // Later, stop listening handle.stop(); ``` ## Example: File Monitor Plugin This example creates a plugin that monitors all file operations and logs them: ```ts import type { Caido } from "@caido/sdk-frontend"; export type CaidoSDK = Caido; export const init = (sdk: CaidoSDK) => { // Monitor file uploads sdk.files.onUploadedHostedFile((file) => { sdk.log.info(`[File Monitor] Uploaded: ${file.name} (${file.path})`); }); // Monitor file updates sdk.files.onUpdatedHostedFile((file) => { sdk.log.info(`[File Monitor] Updated: ${file.name} (${file.path})`); }); // Monitor file deletions sdk.files.onDeletedHostedFile((fileId) => { sdk.log.info(`[File Monitor] Deleted: ${fileId}`); }); sdk.log.info("File monitor plugin initialized"); }; ``` --- --- url: /plugins/guides/slots.md --- # Add to UI Slots UI slots allow you to extend Caido's interface by adding custom components to specific locations, such as toolbars and footers. You can add buttons, commands, or custom components to these slots. ## Finding Available Slots ### Footer Slots Footer slots are available via `sdk.footer.addToSlot()`: * `FooterSlot.FooterSlotPrimary` - Primary footer slot * `FooterSlot.FooterSlotSecondary` - Secondary footer slot ### Replay Slots Replay slots are available via `sdk.replay.addToSlot()`: * `ReplaySlot.SessionToolbarPrimary` - Left side of the session toolbar * `ReplaySlot.SessionToolbarSecondary` - Right side of the session toolbar * `ReplaySlot.Topbar` - Topbar area ## Adding Different Types of Content to Slots You can add three types of content to slots: ### Button A button with a label, icon, and click handler: ```ts sdk.footer.addToSlot(FooterSlot.FooterSlotPrimary, { kind: "Button", label: "My Button", icon: "fas fa-rocket", onClick: () => { console.log("Button clicked"); }, }); ``` ### Command A button that triggers a registered command: ```ts // First register the command sdk.commands.register("my-command", { name: "My Command", run: () => { sdk.window.showToast("Command executed", { variant: "info" }); }, }); // Then add to slot sdk.footer.addToSlot(FooterSlot.FooterSlotPrimary, { kind: "Command", commandId: "my-command", icon: "fas fa-star", }); ``` ### Custom Component A custom Vue component from a `.vue` file: ```vue ``` ```ts import CustomStatus from "./CustomStatus.vue"; sdk.footer.addToSlot(FooterSlot.FooterSlotSecondary, { kind: "Custom", component: { component: CustomStatus, }, }); ``` ## Component Props Custom slot components automatically receive the SDK as an implicit prop. You don't need to pass it explicitly when registering the component. If your Vue component defines an `sdk` prop, it will automatically receive the SDK instance: ```vue ``` ## Importing Slot Constants You need to import the slot constants: ```ts import { FooterSlot } from "@caido/sdk-frontend"; import { ReplaySlot } from "@caido/sdk-frontend"; ``` ## Best Practices * Use buttons for simple actions that don't need command registration * Use commands when you want the action to be available in multiple places (command palette, menus, etc.) * Use custom components for complex UI or dynamic content * Keep slot content concise to maintain a clean interface * Consider the visual hierarchy when adding multiple items to the same slot ::: warning Be mindful of slot space limitations. Too many items in a slot can clutter the interface. Consider grouping related actions or using custom components to organize multiple controls. ::: ::: tip Slots are a powerful way to extend Caido's UI without creating custom pages. Use them to add plugin-specific functionality that integrates seamlessly with the existing interface. ::: ::: info Slot content is rendered when the relevant page is active. For footer slots, content is always visible. For Replay slots, content is only visible on the Replay page. ::: ## Examples ### Footer Actions This example demonstrates adding multiple types of content to footer slots: a button with a click handler, a command button, and a custom status indicator component. First, create the status indicator component: ```vue ``` Then, register all slot content types: ```ts import type { Caido } from "@caido/sdk-frontend"; import { FooterSlot } from "@caido/sdk-frontend"; import StatusIndicator from "./StatusIndicator.vue"; export type CaidoSDK = Caido; export const init = (sdk: CaidoSDK) => { // Register a command sdk.commands.register("quick-action", { name: "Quick Action", run: () => { sdk.window.showToast("Quick action executed", { variant: "success" }); }, }); // Add button to primary footer slot sdk.footer.addToSlot(FooterSlot.FooterSlotPrimary, { kind: "Button", label: "Custom Action", icon: "fas fa-bolt", onClick: () => { sdk.log.info("Custom action triggered"); }, }); // Add command to primary footer slot sdk.footer.addToSlot(FooterSlot.FooterSlotPrimary, { kind: "Command", commandId: "quick-action", icon: "fas fa-star", }); // Add custom component to secondary footer slot sdk.footer.addToSlot(FooterSlot.FooterSlotSecondary, { kind: "Custom", component: { component: StatusIndicator, }, }); }; ``` ### Dynamic Slot Content This example creates a custom component that tracks and displays a click counter. The button updates its label each time it's clicked and shows a toast notification. First, create a Vue component with reactive state. The SDK is automatically passed as a prop, so you only need to define it in the component: ```vue ``` Then, register the component in a slot. You don't need to pass the SDK prop explicitly: ```ts import type { Caido } from "@caido/sdk-frontend"; import { FooterSlot } from "@caido/sdk-frontend"; import ClickCounter from "./ClickCounter.vue"; export type CaidoSDK = Caido; export const init = (sdk: CaidoSDK) => { sdk.footer.addToSlot(FooterSlot.FooterSlotPrimary, { kind: "Custom", component: { component: ClickCounter, }, }); }; ``` --- --- url: /plugins/guides/view_modes.md --- # Add View Modes Add custom view modes to display requests in alternative formats, such as custom parsers, formatted views, or visual editors. Custom view modes appear alongside the default view options in the request viewer. ::: tip Custom view modes are great for domain-specific request formats or when you need specialized visualization of request data. ::: ## Registering a View Mode ### Request View Modes Call `addRequestViewMode()` on the appropriate SDK method for the page where you want the view mode to appear: * HTTP History: `sdk.httpHistory.addRequestViewMode()` * Replay: `sdk.replay.addRequestViewMode()` * Search: `sdk.search.addRequestViewMode()` * Sitemap: `sdk.sitemap.addRequestViewMode()` * Automate: `sdk.automate.addRequestViewMode()` * Intercept: `sdk.intercept.addRequestViewMode()` * Findings: `sdk.findings.addRequestViewMode()` ### Response View Modes Response view modes are also available on pages that display responses. Call `addResponseViewMode()` on the appropriate SDK method: * HTTP History: `sdk.httpHistory.addResponseViewMode()` * Replay: `sdk.replay.addResponseViewMode()` * Search: `sdk.search.addResponseViewMode()` * Sitemap: `sdk.sitemap.addResponseViewMode()` * Automate: `sdk.automate.addResponseViewMode()` * Intercept: `sdk.intercept.addResponseViewMode()` * Findings: `sdk.findings.addResponseViewMode()` ::: info View modes are available on all pages that display requests and responses. Consider adding your view mode to multiple pages if it's useful across different contexts. ::: ```ts sdk.httpHistory.addRequestViewMode({ label: "My Custom View", view: { component: MyComponent, }, }); ``` The `label` is the display name shown in the view mode selector. The `view.component` is your Vue component that renders the custom view. ## Using Component Props ### Request View Mode Props Request view mode components automatically receive these props—you don't need to pass them when registering: * `sdk` - The Caido SDK instance * `request` - The request object of type `RequestFull` * `requestDraft` - A writable request object of type `RequestDraft` (only in Intercept and Replay contexts) ::: warning The request object structure may vary between pages. Test your view mode on the pages where you add it to ensure compatibility. ::: For read-only contexts (HTTP History, Search, etc.): ```vue ``` For writable contexts (Intercept, Replay): ```vue ``` ### Response View Mode Props Response view mode components automatically receive these props: * `sdk` - The Caido SDK instance * `response` - The response object of type `ResponseFull` * `request` - The associated request object of type `RequestMeta` or `RequestFull` ```vue ``` ## Examples ### JSON Formatter View A view mode that formats request bodies as pretty-printed JSON, displaying an error message if the body isn't valid JSON. ```vue ``` ```ts import type { Caido } from "@caido/sdk-frontend"; import JSONFormatterView from "./JSONFormatterView.vue"; export type CaidoSDK = Caido; export const init = (sdk: CaidoSDK) => { sdk.httpHistory.addRequestViewMode({ label: "JSON Formatter", view: { component: JSONFormatterView, }, }); }; ``` ### Editable Request View A view mode for Intercept or Replay that allows editing the request using the `requestDraft` prop. ```vue