### EdgeConfigClientOptions Examples Source: https://github.com/vercel/storage/blob/main/_autodocs/edge-config-types.md Illustrates creating clients with different caching strategies for static and dynamic pages. ```typescript // For Next.js static pages const staticClient = createClient(process.env.EDGE_CONFIG, { cache: 'force-cache', }); // For dynamic pages with fallback const dynamicClient = createClient(process.env.EDGE_CONFIG, { cache: 'no-store', staleIfError: 86400, // 1 day fallback }); ``` -------------------------------- ### Install @vercel/blob package Source: https://github.com/vercel/storage/blob/main/packages/blob/README.md Command to install the Vercel Blob client library via npm. ```shell npm install @vercel/blob ``` -------------------------------- ### Basic Read Source: https://github.com/vercel/storage/blob/main/_autodocs/edge-config-client.md Demonstrates how to retrieve a single configuration value or check for its existence using the `get` and `has` functions. ```APIDOC ## Basic Read Retrieve a single configuration value or check for its existence. ### Functions - `get(key: string)`: Retrieves the value associated with the given key. - `has(key: string)`: Returns `true` if the key exists, `false` otherwise. ### Example ```typescript import { get, has } from '@vercel/edge-config'; const featureEnabled = await get('features.newUI'); const exists = await has('settings.theme'); ``` ``` -------------------------------- ### File Browser Setup Source: https://github.com/vercel/storage/blob/main/_autodocs/blob-create-folder.md Sets up a project-specific folder structure and then lists the created folders using `list` with `mode: 'folded'`. ```typescript import { createFolder, list } from '@vercel/blob'; async function setupProjectStructure(projectId) { // Create folder structure const folderPaths = [ `projects/${projectId}/`, `projects/${projectId}/uploads/`, `projects/${projectId}/media/`, `projects/${projectId}/archives/`, ]; for (const path of folderPaths) { await createFolder(path); } // Verify structure with folded listing const { folders } = await list({ prefix: `projects/${projectId}/`, mode: 'folded', }); console.log('Project folders:', folders); } ``` -------------------------------- ### EdgeConfigItems Example Source: https://github.com/vercel/storage/blob/main/_autodocs/edge-config-types.md Demonstrates the structure of an EdgeConfigItems object with various data types. ```typescript const config: EdgeConfigItems = { apiUrl: "https://api.example.com", timeout: 5000, featureFlags: { newUI: true, betaFeatures: false, }, allowed_regions: ["us-east-1", "eu-west-1"], }; ``` -------------------------------- ### Connection Type Example Source: https://github.com/vercel/storage/blob/main/_autodocs/edge-config-types.md Shows how to access connection details from an EdgeConfigClient instance. ```typescript const client = createClient(process.env.EDGE_CONFIG); const { id, type, baseUrl } = client.connection; console.log(`Connected to ${type} Edge Config: ${id}`); ``` -------------------------------- ### Check File Size Before Download Source: https://github.com/vercel/storage/blob/main/_autodocs/blob-head.md Before downloading a file, use `head` to get its metadata and check its size. This example prevents downloading files larger than 100MB. ```typescript import { head, get } from '@vercel/blob'; const metadata = await head('media/video.mp4'); // Only download if file is smaller than 100MB if (metadata.size < 100 * 1024 * 1024) { const result = await get('media/video.mp4', { access: 'public' }); // Process download } else { console.log(`File too large: ${metadata.size} bytes`); } ``` -------------------------------- ### Manual Multipart Upload Example (TypeScript) Source: https://github.com/vercel/storage/blob/main/_autodocs/blob-multipart.md Demonstrates how to manually perform a multipart upload for a large file by creating, uploading parts, and completing the upload. ```typescript import { createMultipartUpload, uploadPart, completeMultipartUpload } from '@vercel/blob'; import fs from 'fs'; async function uploadLargeFile(filePath) { // 1. Start multipart upload const { uploadId, key } = await createMultipartUpload('videos/large-file.mp4', { access: 'public', contentType: 'video/mp4', }); const partSize = 5 * 1024 * 1024; // 5MB per part const fileContent = fs.readFileSync(filePath); const parts = []; // 2. Upload parts for (let i = 0; i < fileContent.length; i += partSize) { const partNumber = Math.floor(i / partSize) + 1; const chunk = fileContent.slice(i, i + partSize); const { etag } = await uploadPart('videos/large-file.mp4', chunk, { uploadId, key, partNumber, access: 'public', }); parts.push({ etag, partNumber }); console.log(`Uploaded part ${partNumber}`); } // 3. Finalize const result = await completeMultipartUpload('videos/large-file.mp4', parts, { uploadId, key, access: 'public', }); console.log(`Upload complete: ${result.url}`); return result; } ``` -------------------------------- ### get() Function Signature Source: https://github.com/vercel/storage/blob/main/_autodocs/blob-get.md The signature for the get() function, which takes a URL or pathname and options, returning blob data or null. ```APIDOC ## get() ### Description Fetches blob content and metadata by URL or pathname. Returns a readable stream (no buffering) and blob metadata. Supports conditional requests using ETags to avoid re-downloading unchanged blobs. ### Signature ```typescript export async function get( urlOrPathname: string, options: GetCommandOptions ): Promise ``` ### Parameters #### Path Parameters - **urlOrPathname** (string) - Required - Blob URL (e.g., `https://abc123.public.blob.vercel-storage.com/path/file.txt`) or pathname (e.g., `path/file.txt`) #### Request Body - **options** (GetCommandOptions) - Required - Configuration object with access level and optional settings ### GetCommandOptions #### Options - **access** ('public' | 'private') - Required - Blob access level. Must match the blob's actual access setting - **token** (string) - Optional - Bearer token for authentication (required if blob is private). Defaults to `process.env.BLOB_READ_WRITE_TOKEN`. - **oidcToken** (string) - Optional - Vercel OIDC token (used with storeId for private blobs). Defaults to `process.env.VERCEL_OIDC_TOKEN`. - **storeId** (string) - Optional - Blob store identifier (used with oidcToken for private blobs). Defaults to `process.env.BLOB_STORE_ID`. - **abortSignal** (AbortSignal) - Optional - Cancel operation via AbortController. - **ifNoneMatch** (string) - Optional - ETag value for conditional fetch. Returns 304 (not modified) if blob ETag matches. - **headers** (HeadersInit) - Optional - Additional fetch headers. Authorization header is set automatically. - **useCache** (boolean) - Optional - Deprecated. Has no effect. Kept for backward compatibility. ``` -------------------------------- ### List Blobs (Default/Expanded Mode) Source: https://github.com/vercel/storage/blob/main/_autodocs/blob-list.md This example demonstrates how to list blobs using the default 'expanded' mode, which returns detailed information for each blob. It also shows how to iterate through the results and check for more available data. ```APIDOC ## List Blobs (Default/Expanded Mode) ### Description Lists blobs with detailed information in expanded mode. ### Method ```typescript list() ``` ### Parameters None ### Response #### Success Response - **blobs** (ListBlobResultBlob[]) - Array of blob objects at current level. - **cursor** (string | undefined) - Pagination cursor for next request. - **hasMore** (boolean) - Whether more results are available. ### Request Example ```typescript import { list } from '@vercel/blob'; const { blobs, hasMore, cursor } = await list(); for (const blob of blobs) { console.log(`${blob.pathname} - ${blob.size} bytes`); } if (hasMore) { console.log(`More results available. Cursor: ${cursor}`); } ``` ``` -------------------------------- ### Install @vercel/edge-config Source: https://github.com/vercel/storage/blob/main/packages/edge-config/README.md Installs the @vercel/edge-config package using npm. This is the first step to using the library in your project. ```sh npm install @vercel/edge-config ``` -------------------------------- ### Install dotenv and dotenv-expand for Vite Development Source: https://github.com/vercel/storage/blob/main/packages/edge-config/README.md Installs the necessary packages to expand environment variables in Vite development environments. This is a prerequisite for the first configuration method. ```shell pnpm install --save-dev dotenv dotenv-expand ``` -------------------------------- ### EdgeConfigValue Examples Source: https://github.com/vercel/storage/blob/main/_autodocs/edge-config-types.md Illustrates various types of values that can be assigned to EdgeConfigValue. ```typescript const stringValue: EdgeConfigValue = "hello"; ``` ```typescript const numberValue: EdgeConfigValue = 42; ``` ```typescript const booleanValue: EdgeConfigValue = true; ``` ```typescript const nullValue: EdgeConfigValue = null; ``` ```typescript const objectValue: EdgeConfigValue = { a: 1, b: "text" }; ``` ```typescript const arrayValue: EdgeConfigValue = [1, "text", { nested: true }]; ``` ```typescript const deepNested: EdgeConfigValue = { level1: { level2: { level3: [1, 2, 3] } } }; ``` -------------------------------- ### List Blobs with Prefix Filter Source: https://github.com/vercel/storage/blob/main/_autodocs/blob-list.md This example shows how to filter the list of blobs by providing a 'prefix'. This is useful for retrieving blobs located within a specific folder or path. ```APIDOC ## List Blobs with Prefix Filter ### Description Lists blobs filtered by a specified prefix (folder path). ### Method ```typescript list({ prefix: string }) ``` ### Parameters #### Query Parameters - **prefix** (string) - Required - The prefix to filter blobs by (e.g., 'documents/'). ### Response #### Success Response - **blobs** (ListBlobResultBlob[]) - Array of blob objects matching the prefix. ### Request Example ```typescript import { list } from '@vercel/blob'; // Get all blobs under documents/ folder const { blobs } = await list({ prefix: 'documents/', }); console.log(`Found ${blobs.length} documents`); for (const blob of blobs) { console.log(`- ${blob.pathname}`); } ``` ``` -------------------------------- ### Copy Blob with Metadata Source: https://github.com/vercel/storage/blob/main/_autodocs/blob-copy.md This example demonstrates how to copy a blob and explicitly set its metadata, such as access level and content type, by retrieving the source blob's metadata first. ```APIDOC ## copy ### Description Copies a blob from a source pathname to a destination pathname within the same Vercel Blob store. Metadata such as content type and access level can be specified. ### Method `copy(from: string, to: string, options?: { access?: 'public' | 'private'; contentType?: string; oidcToken?: string; storeId?: string }) => Promise<{ pathname: string; url: string; ... }>` ### Parameters #### Path Parameters None explicitly defined, uses pathnames in the function arguments. #### Query Parameters None #### Request Body Not applicable for this SDK method. ### Options Object - **access** (string) - Required/Optional - Specifies the access level for the copied blob. Can be 'public' or 'private'. Defaults to 'private' if not specified. - **contentType** (string) - Required/Optional - Explicitly sets the content type of the copied blob. If not provided, it's inferred from the destination pathname's extension, falling back to 'application/octet-stream'. - **oidcToken** (string) - Required/Optional - An OIDC token for authentication, used in specific authentication flows. - **storeId** (string) - Required/Optional - The ID of the Vercel Blob store to use. ### Request Example ```typescript import { copy } from '@vercel/blob'; // Example 1: Copying with explicit metadata const sourceMetadata = await head('source/file.txt'); // Assuming 'head' is available to get metadata const archived = await copy('source/file.txt', 'archive/2023/10/file.txt', { access: 'private', contentType: sourceMetadata.contentType, }); // Example 2: Copying with OIDC authentication const copied = await copy( 'source/file.dat', 'destination/file.dat', { access: 'private', oidcToken: process.env.VERCEL_OIDC_TOKEN, storeId: process.env.BLOB_STORE_ID, } ); ``` ### Response #### Success Response Returns an object containing information about the copied blob, including its `pathname` and `url`. - **pathname** (string) - The pathname of the copied blob. - **url** (string) - The URL of the copied blob. #### Response Example ```json { "pathname": "destination/file.dat", "url": "https://.vercel.app/destination/file.dat" } ``` ### Notes - Metadata like `cacheControlMaxAge` is NOT automatically copied. - Source and destination must be in the same Vercel Blob store. - Access control must be explicitly specified. - Pathname has a maximum length of 950 characters and disallowed characters. ``` -------------------------------- ### Get All Edge Config Values Source: https://github.com/vercel/storage/blob/main/_autodocs/edge-config-client.md Retrieve all configuration values using `getAll`. You can optionally specify a subset of keys to fetch. This is useful for loading all feature flags or settings at once. ```typescript import { createClient } from '@vercel/edge-config'; const handler: VercelFunction = async (request) => { const edgeConfig = createClient(process.env.EDGE_CONFIG); const config = await edgeConfig.getAll(); return Response.json(config); }; ``` -------------------------------- ### Create and Use Multiple Edge Config Clients Source: https://github.com/vercel/storage/blob/main/_autodocs/edge-config-configuration.md Instantiate multiple Edge Config clients using different environment variables for distinct configuration stores. Useful for separating feature flags, tenant configurations, or A/B testing setups. ```typescript import { createClient } from '@vercel/edge-config'; const primaryConfig = createClient( process.env.EDGE_CONFIG_PRIMARY ); const secondaryConfig = createClient( process.env.EDGE_CONFIG_SECONDARY ); const primary = await primaryConfig.get('key'); const secondary = await secondaryConfig.get('key'); ``` ```bash # .env.local EDGE_CONFIG_PRIMARY="https://edge-config.vercel.com/ecfg_primary?token=..." EDGE_CONFIG_SECONDARY="https://edge-config.vercel.com/ecfg_secondary?token=..." ``` -------------------------------- ### GetCommandOptions Source: https://github.com/vercel/storage/blob/main/_autodocs/blob-types.md Options for the `get()` operation, allowing control over access, caching, and conditional retrieval. ```APIDOC ## GetCommandOptions ```typescript interface GetCommandOptions extends BlobCommandOptions { access: BlobAccessType; useCache?: boolean; ifNoneMatch?: string; headers?: HeadersInit; } ``` Options for `get()` operation. ``` -------------------------------- ### Parsed Connection Object Example Source: https://github.com/vercel/storage/blob/main/_autodocs/edge-config-types.md Demonstrates the structure of the parsed connection object obtained after parsing a connection string, showing its properties like type, baseUrl, id, token, and version. ```typescript interface ParsedConnection { type: 'vercel' | 'external'; baseUrl: string; // https://edge-config.vercel.com/ecfg_xxx id: string; // ecfg_xxx or config-123 token: string; // Bearer token version: string; // API version } const client = createClient('https://edge-config.vercel.com/ecfg_abc?token=xyz'); console.log(client.connection); // { // type: 'vercel', // baseUrl: 'https://edge-config.vercel.com/ecfg_abc', // id: 'ecfg_abc', // token: 'xyz', // version: '1' // } ``` -------------------------------- ### Copy Blob Basic Example Source: https://github.com/vercel/storage/blob/main/_autodocs/blob-copy.md This snippet demonstrates how to copy a blob from one path to another with public access. It logs the URL and pathname of the newly copied blob. ```typescript import { copy } from '@vercel/blob'; const copied = await copy( 'documents/original.pdf', 'documents/backup.pdf', { access: 'public' } ); console.log(`Copied to: ${copied.url}`); console.log(`Pathname: ${copied.pathname}`); ``` -------------------------------- ### Next.js Server Component with Dynamic Rendering Source: https://github.com/vercel/storage/blob/main/_autodocs/edge-config-configuration.md Example of using a client configured with `cache: 'no-store'` within a Next.js Server Component to ensure dynamic rendering and fetching fresh configuration data on each request. ```typescript // Next.js Server Component with dynamic rendering const dynamicConfig = createClient( process.env.EDGE_CONFIG, { cache: 'no-store' } ); export default async function Page() { const config = await dynamicConfig.get('key'); return
{config}
; } ``` -------------------------------- ### Use Default Edge Config Client Source: https://github.com/vercel/storage/blob/main/_autodocs/edge-config-configuration.md Import and use the default client methods like `get`, `getAll`, `has`, and `digest` directly. These methods automatically utilize the `EDGE_CONFIG` environment variable for connection. ```typescript import { get, getAll, has, digest } from '@vercel/edge-config'; // Uses default client from environment variable const value = await get('key'); ``` -------------------------------- ### Get multiple or all values using EdgeConfigClient Source: https://github.com/vercel/storage/blob/main/_autodocs/edge-config-client.md Use the `getAll` method on an `EdgeConfigClient` instance to fetch all configuration values or a specified subset of keys. This method returns an object containing the requested configuration items. ```typescript // Get all const allConfig = await client.getAll(); // Get specific keys const features = await client.getAll<{ flagA: boolean; flagB: boolean }>(['flagA', 'flagB']); ``` -------------------------------- ### Get multiple or all values from default Edge Config Source: https://github.com/vercel/storage/blob/main/_autodocs/edge-config-client.md Use the default `getAll` method to retrieve all configuration values or a specific subset of keys from Edge Config. This is useful for fetching multiple settings at once. ```typescript export const getAll: EdgeConfigClient['getAll'] ``` ```typescript import { getAll } from '@vercel/edge-config'; // Get all values const allData = await getAll(); // Get specific keys const subset = await getAll(['keyA', 'keyB']); ``` -------------------------------- ### Short Fallback for Frequently Changing Config Source: https://github.com/vercel/storage/blob/main/_autodocs/edge-config-configuration.md Example of configuring a client with a short `staleIfError` duration (1 hour) for frequently updated configuration values, minimizing the impact of service outages. ```typescript // Short fallback for frequently-changing config const shortFallback = createClient( process.env.EDGE_CONFIG, { staleIfError: 3600 } // 1 hour fallback ); ``` -------------------------------- ### Create and use EdgeConfigClient Source: https://github.com/vercel/storage/blob/main/_autodocs/edge-config-client.md Instantiate the `EdgeConfigClient` with your Edge Config connection string to interact with configuration values. This client provides methods for getting, checking, and retrieving digests. ```typescript const client = createClient(process.env.EDGE_CONFIG); ``` -------------------------------- ### Get Blob using Pathname vs. Full URL Source: https://github.com/vercel/storage/blob/main/_autodocs/blob-get.md Demonstrates two equivalent ways to fetch a blob: using a relative pathname (inferring store ID from token) and using the full blob URL. Both require the 'public' access level. ```typescript import { get } from '@vercel/blob'; // Both of these are equivalent: // Option 1: Pathname (requires storeId inference from token) const result1 = await get('documents/file.txt', { access: 'public', token: process.env.BLOB_READ_WRITE_TOKEN, }); // Option 2: Full URL (storeId comes from domain) const result2 = await get( 'https://abc123.public.blob.vercel-storage.com/documents/file.txt', { access: 'public' } ); ``` -------------------------------- ### Handle Edge Config Errors Source: https://github.com/vercel/storage/blob/main/_autodocs/edge-config-client.md Demonstrates how to catch and handle various errors that can occur when fetching data from Edge Config, such as invalid tokens or missing configurations. Ensure you import the `get` function from '@vercel/edge-config'. ```typescript import { get } from '@vercel/edge-config'; try { const value = await get('key'); } catch (error) { if (error.message.includes('Unauthorized')) { console.error('Invalid token'); } else if (error.message.includes('not found')) { console.error('Edge Config deleted'); } else { console.error('Network error:', error); } } ``` -------------------------------- ### get() Return Type Source: https://github.com/vercel/storage/blob/main/_autodocs/edge-config-types.md Returns the value if the key exists, or `undefined` if not found. Can be typed with `get()` for type-safe access. ```APIDOC ## get() ### Description Returns the value if key exists, `undefined` if not found. ### Return Type ```typescript Promise ``` ### Generic Can be typed with `get()` for type-safe access. ### Example ```typescript const url: string | undefined = await get('apiUrl'); const config: MyConfig | undefined = await get('settings'); ``` ``` -------------------------------- ### Configure Edge Config for Next.js Pages Router (getStaticProps) Source: https://github.com/vercel/storage/blob/main/_autodocs/edge-config-configuration.md Set up Edge Config for use within `getStaticProps` in the Next.js Pages Router. This example demonstrates fetching all data and configuring Incremental Static Regeneration (ISR). ```typescript // pages/index.tsx import { createClient } from '@vercel/edge-config'; const config = createClient(process.env.EDGE_CONFIG); export async function getStaticProps() { const data = await config.getAll(); return { props: { data }, revalidate: 3600, // ISR }; } export default function Page({ data }) { return
{JSON.stringify(data)}
; } ``` -------------------------------- ### get() Return Type Source: https://github.com/vercel/storage/blob/main/_autodocs/edge-config-types.md Returns the value if the key exists, or undefined if not found. Can be typed with `get()` for type-safe access. ```typescript Promise ``` ```typescript const url: string | undefined = await get('apiUrl'); const config: MyConfig | undefined = await get('settings'); ``` -------------------------------- ### User Upload Directories Initialization Source: https://github.com/vercel/storage/blob/main/_autodocs/blob-create-folder.md Initializes storage directories for a user, creating multiple private folders concurrently using `Promise.all`. ```typescript import { createFolder } from '@vercel/blob'; async function initializeUserStorage(userId) { const basePath = `users/${userId}/`; const folders = [ `${basePath}`, `${basePath}documents/`, `${basePath}media/`, `${basePath}backups/`, ]; const results = await Promise.all( folders.map(path => createFolder(path, { access: 'private' })) ); return results; } ``` -------------------------------- ### Read Multiple Keys Source: https://github.com/vercel/storage/blob/main/_autodocs/edge-config-client.md Shows how to fetch multiple configuration values simultaneously using the `getAll` function. ```APIDOC ## Read Multiple Keys Retrieve multiple configuration values at once. ### Function - `getAll(keys: string[])`: Returns an object with keys and their corresponding values. ### Example ```typescript import { getAll } from '@vercel/edge-config'; const { feature1, feature2, feature3 } = await getAll(['feature1', 'feature2', 'feature3']); ``` ``` -------------------------------- ### Create Client Source: https://github.com/vercel/storage/blob/main/_autodocs/edge-config-client.md Demonstrates how to create a custom Edge Config client, allowing for multiple configurations or specific caching strategies. ```APIDOC ## Create Client Create a custom client instance for Edge Config. ### Function - `createClient(url: string, options?: EdgeConfigFunctionsOptions)`: Creates a new Edge Config client. ### Options - `cache` (string, optional): Specifies the caching strategy (e.g., 'force-cache'). - `consistentRead` (boolean, optional): Bypass caches and hit origin directly for fresh data. ### Example: Multiple Edge Configs ```typescript import { createClient } from '@vercel/edge-config'; const primaryConfig = createClient(process.env.EDGE_CONFIG); const secondaryConfig = createClient(process.env.SECONDARY_EDGE_CONFIG); const primary = await primaryConfig.get('setting'); const secondary = await secondaryConfig.get('setting'); ``` ### Example: Static Page Caching (Next.js) ```typescript import { createClient } from '@vercel/edge-config'; const edgeConfig = createClient(process.env.EDGE_CONFIG, { cache: 'force-cache', // Enables static generation }); // Use in Next.js Server Component or getStaticProps const data = await edgeConfig.get('staticData'); ``` ### Example: Consistent Read (ISR) ```typescript import { createClient } from '@vercel/edge-config'; const client = createClient(process.env.EDGE_CONFIG); // For Incremental Static Regeneration, ensure fresh data const config = await client.get('revalidationTrigger', { consistentRead: true, }); ``` ``` -------------------------------- ### Type-Safe Get with @vercel/blob Source: https://github.com/vercel/storage/blob/main/_autodocs/README.md Use generic types with the `get()` function for type-safe retrieval of blob data. Specify the expected data structure within the angle brackets. ```typescript // @vercel/blob const result = await get<{ name: string; size: number }>('data.json', { access: 'public', }); ``` -------------------------------- ### Type-Safe Get with @vercel/edge-config Source: https://github.com/vercel/storage/blob/main/_autodocs/README.md Retrieve configuration values with type safety using generic types for the `get()` and `getAll()` functions. This ensures the retrieved data conforms to the specified structure. ```typescript // @vercel/edge-config const config = await get<{ apiUrl: string }>('settings'); const all = await getAll<{ apiUrl: string; timeout: number }>(); ``` -------------------------------- ### List Metadata for Multiple Files Source: https://github.com/vercel/storage/blob/main/_autodocs/blob-head.md Demonstrates how to fetch metadata for multiple files concurrently using Promise.all and the head() function. ```APIDOC ## List Metadata for Multiple Files This example shows how to efficiently retrieve metadata for several files at once by mapping over an array of filenames and calling `head()` for each, then aggregating the results. ### Usage ```typescript import { head } from '@vercel/blob'; const files = ['doc1.pdf', 'doc2.pdf', 'doc3.pdf']; const metadata = await Promise.all( files.map(file => head(file)) ); const totalSize = metadata.reduce((sum, m) => sum + m.size, 0); console.log(`Total size of ${files.length} files: ${totalSize} bytes`); ``` ### Notes - This approach leverages `Promise.all` for parallel execution, making it faster than sequential calls. - The `metadata` array will contain objects with file information such as `name`, `size`, `etag`, `contentType`, `contentDisposition`, and `cacheControl`. ``` -------------------------------- ### Blob Get Return Type Definition Source: https://github.com/vercel/storage/blob/main/_autodocs/blob-get.md Defines the possible return types for the blob get operation, including full content, a 304 status, or null for non-existent blobs. ```typescript type GetBlobResult = | { statusCode: 200; stream: ReadableStream; headers: Headers; blob: { url: string; downloadUrl: string; pathname: string; contentType: string; contentDisposition: string; cacheControl: string; uploadedAt: Date; size: number; etag: string; }; } | { statusCode: 304; stream: null; headers: Headers; blob: { url: string; downloadUrl: string; pathname: string; contentType: null; contentDisposition: string; cacheControl: string; uploadedAt: Date; size: null; etag: string; }; } | null ``` -------------------------------- ### Get a single value using EdgeConfigClient Source: https://github.com/vercel/storage/blob/main/_autodocs/edge-config-client.md Use the `get` method on an `EdgeConfigClient` instance to retrieve a specific configuration value by its key. You can specify the expected type of the value and optional read consistency options. ```typescript const apiUrl = await client.get('api.url'); const settings = await client.get<{ timeout: number }>('api.settings'); ``` -------------------------------- ### Local Development Environment Variables Source: https://github.com/vercel/storage/blob/main/_autodocs/blob-configuration.md Set up environment variables in `.env.local` for local development with Vercel Blob. This includes read/write tokens and a store ID for testing. ```bash # .env.local for local development BLOB_READ_WRITE_TOKEN=vercel_blob_rw_test_xxxxxxx BLOB_STORE_ID=local-test-store ``` -------------------------------- ### Get a single value from default Edge Config Source: https://github.com/vercel/storage/blob/main/_autodocs/edge-config-client.md Use the default `get` method to read a single value from Edge Config using `process.env.EDGE_CONFIG`. Ensure the key exists before attempting to retrieve its value. ```typescript export const get: EdgeConfigClient['get'] ``` ```typescript import { get } from '@vercel/edge-config'; const value = await get('someKey'); ``` -------------------------------- ### Create Client for Multiple Edge Configs Source: https://github.com/vercel/storage/blob/main/_autodocs/edge-config-client.md Initializes separate clients for different Edge Configs using their respective environment variables. Allows fetching data from distinct configurations. ```typescript import { createClient } from '@vercel/edge-config'; const primaryConfig = createClient(process.env.EDGE_CONFIG); const secondaryConfig = createClient(process.env.SECONDARY_EDGE_CONFIG); const primary = await primaryConfig.get('setting'); const secondary = await secondaryConfig.get('setting'); ``` -------------------------------- ### Check for Updates Source: https://github.com/vercel/storage/blob/main/_autodocs/edge-config-client.md Explains how to get a digest of the Edge Config to detect changes. ```APIDOC ## Check for Updates Get a digest of the Edge Config to detect changes. ### Function - `digest()`: Returns a string representing the current digest of the Edge Config. ### Example ```typescript import { digest } from '@vercel/edge-config'; const currentDigest = await digest(); // Store and compare later to detect changes ``` ``` -------------------------------- ### CreateFolderCommandOptions Source: https://github.com/vercel/storage/blob/main/_autodocs/blob-types.md Options for the `createFolder()` operation, allowing specification of access control and token. ```APIDOC ## CreateFolderCommandOptions ```typescript interface CreateFolderCommandOptions extends Pick { access?: BlobAccessType; } ``` Options for `createFolder()` operation. ``` -------------------------------- ### Create and Delete Folder Source: https://github.com/vercel/storage/blob/main/_autodocs/blob-create-folder.md Shows the lifecycle of creating a folder and then deleting it using the `del` function with the folder's URL. ```typescript import { createFolder, del } from '@vercel/blob'; // Create folder const folder = await createFolder('temp/'); // Later, delete the folder await del(folder.url); console.log('Folder deleted'); ``` -------------------------------- ### createFolder() Source: https://github.com/vercel/storage/blob/main/_autodocs/blob-create-folder.md Creates a folder placeholder in your Vercel Blob store. Folders are simulated using trailing slashes in pathnames and are primarily useful for file browser interfaces. ```APIDOC ## createFolder() ### Description Creates a folder placeholder in your Vercel Blob store. Vercel Blob has no real concept of folders—they are simulated using trailing slashes in pathnames. This function is primarily useful for file browser interfaces. ### Signature ```typescript export async function createFolder( pathname: string, options?: CreateFolderCommandOptions ): Promise ``` ### Parameters #### Path Parameters - **pathname** (string) - Required - Folder path. Can be `user1/` or `user1/avatars/`. Trailing slash is added if omitted #### Request Body - **options** (CreateFolderCommandOptions) - Optional - Configuration object. Defaults to `{ access: 'public' }` - **access** ('public' | 'private') - Optional - Folder access level (for backward compatibility). Defaults to 'public'. - **token** (string) - Optional - Bearer token for API authentication. Defaults to `process.env.BLOB_READ_WRITE_TOKEN`. - **abortSignal** (AbortSignal) - Optional - Cancel operation via AbortController. ### Return Type #### Success Response (200) - **pathname** (string) - The created folder pathname (guaranteed to end with `/`). - **url** (string) - Full URL for the folder (can be used to delete the folder). ### Request Example ```typescript import { createFolder } from '@vercel/blob'; const folder = await createFolder('documents/'); console.log(`Folder created at: ${folder.pathname}`); console.log(`Folder URL: ${folder.url}`); ``` ### Example: Without Trailing Slash ```typescript import { createFolder } from '@vercel/blob'; // Trailing slash is added automatically const folder = await createFolder('documents'); console.log(folder.pathname); // 'documents/' ``` ### Example: Nested Folder Structure ```typescript import { createFolder } from '@vercel/blob'; const folders = [ 'projects/', 'projects/design/', 'projects/design/mockups/', 'projects/development/', ]; for (const folderPath of folders) { const result = await createFolder(folderPath, { access: 'private' }); console.log(`Created: ${result.pathname}`); } ``` ### Example: Delete Folder ```typescript import { createFolder, del } from '@vercel/blob'; // Create folder const folder = await createFolder('temp/'); // Later, delete the folder await del(folder.url); console.log('Folder deleted'); ``` ### Example: File Browser Setup ```typescript import { createFolder, list } from '@vercel/blob'; async function setupProjectStructure(projectId) { // Create folder structure const folderPaths = [ `projects/${projectId}/`, `projects/${projectId}/uploads/`, `projects/${projectId}/media/`, `projects/${projectId}/archives/`, ]; for (const path of folderPaths) { await createFolder(path); } // Verify structure with folded listing const { folders } = await list({ prefix: `projects/${projectId}/`, mode: 'folded', }); console.log('Project folders:', folders); } ``` ### Example: User Upload Directories ```typescript import { createFolder } from '@vercel/blob'; async function initializeUserStorage(userId) { const basePath = `users/${userId}/`; const folders = [ `${basePath}`, `${basePath}documents/`, `${basePath}media/`, `${basePath}backups/`, ]; const results = await Promise.all( folders.map(path => createFolder(path, { access: 'private' })) ); return results; } ``` ``` -------------------------------- ### DelegationOperation Type Source: https://github.com/vercel/storage/blob/main/_autodocs/blob-types.md Defines the allowed operations for signed tokens: get, head, put, and delete. ```typescript type DelegationOperation = 'get' | 'head' | 'put' | 'delete' ``` -------------------------------- ### GetBlobResult Source: https://github.com/vercel/storage/blob/main/_autodocs/blob-types.md Discriminated union type representing the result of the `get()` operation, indicating success or not modified. ```APIDOC ## Type: GetBlobResult ### Description Result from `get()` operation. Discriminated by `statusCode`. ### Status Codes - **200 (Full Response)**: Blob found and returned. - `stream`: ReadableStream of content. - `blob.contentType`: MIME type. - `blob.size`: Content length. - **304 (Not Modified)**: Blob unchanged since ETag. - `stream`: null (no body). - `blob.contentType`: null. - `blob.size`: null. ### Fields - **statusCode** (200 | 304) - Required - The status code of the operation. - **stream** (ReadableStream | null) - Required - The stream of the blob content or null if not modified. - **headers** (Headers) - Required - The response headers. - **blob** ({ url: string; downloadUrl: string; pathname: string; contentType: string | null; contentDisposition: string; cacheControl: string; uploadedAt: Date; size: number | null; etag: string; }) - Required - Blob metadata. ``` -------------------------------- ### Local Development Configuration Source: https://github.com/vercel/storage/blob/main/_autodocs/edge-config-configuration.md Configure local development by setting the EDGE_CONFIG environment variable to a development endpoint. SWR caching is enabled by default. ```bash # .env.local EDGE_CONFIG="https://edge-config.vercel.com/ecfg_dev?token=test_token" ``` -------------------------------- ### get(key) Source: https://github.com/vercel/storage/blob/main/packages/edge-config/README.md Retrieves the value associated with a specific key from the Edge Config store. ```APIDOC ## GET /get ### Description Retrieves a single value from the Edge Config store based on the provided key. ### Method GET ### Parameters #### Query Parameters - **key** (string) - Required - The unique identifier for the configuration item. ### Request Example ```js await get('someKey'); ``` ### Response #### Success Response (200) - **value** (any) - The value associated with the key, or undefined if not found. #### Response Example ```json "value_of_key" ``` ``` -------------------------------- ### List Metadata for Multiple Files Source: https://github.com/vercel/storage/blob/main/_autodocs/blob-head.md Use `Promise.all` with `head` to efficiently retrieve metadata for several files simultaneously. This is useful for calculating aggregate properties like total size. ```typescript import { head } from '@vercel/blob'; const files = ['doc1.pdf', 'doc2.pdf', 'doc3.pdf']; const metadata = await Promise.all( files.map(file => head(file)) ); const totalSize = metadata.reduce((sum, m) => sum + m.size, 0); console.log(`Total size of ${files.length} files: ${totalSize} bytes`); ``` -------------------------------- ### Create a Folder Source: https://github.com/vercel/storage/blob/main/_autodocs/blob-create-folder.md Creates a folder in the Vercel Blob store. A trailing slash is automatically added to the pathname if omitted. ```typescript import { createFolder } from '@vercel/blob'; const folder = await createFolder('documents/'); console.log(`Folder created at: ${folder.pathname}`); console.log(`Folder URL: ${folder.url}`); ``` -------------------------------- ### GetCommandOptions Type Source: https://github.com/vercel/storage/blob/main/_autodocs/blob-types.md Options for the get() operation, specifying access type, cache usage, and conditional retrieval. ```typescript interface GetCommandOptions extends BlobCommandOptions { access: BlobAccessType; useCache?: boolean; ifNoneMatch?: string; headers?: HeadersInit; } ``` -------------------------------- ### Get Public Blob Source: https://github.com/vercel/storage/blob/main/_autodocs/blob-get.md Fetches a public blob and processes its stream. Handles cases where the blob is not found or unchanged. ```typescript import { get } from '@vercel/blob'; const result = await get('documents/file.pdf', { access: 'public' }); if (result === null) { console.log('Blob not found'); } else if (result.statusCode === 200) { const { stream, blob } = result; console.log(`Blob size: ${blob.size} bytes`); console.log(`Content type: ${blob.contentType}`); console.log(`URL: ${blob.url}`); // Process stream for await (const chunk of stream) { // Handle chunk } } else if (result.statusCode === 304) { console.log('Blob unchanged since last check'); } ``` -------------------------------- ### Manage package releases with Changesets Source: https://github.com/vercel/storage/blob/main/packages/blob/README.md Commands to generate a changeset and commit it to the repository for automated publishing. ```shell pnpm changeset git commit -am "changeset" git push ``` -------------------------------- ### Handle BlobRequestAbortedError Source: https://github.com/vercel/storage/blob/main/_autodocs/blob-errors.md Catch this error when a request is aborted, for example, by an AbortSignal. This can happen due to user cancellation or a request timeout. ```typescript export class BlobRequestAbortedError extends BlobError { constructor(); } ``` ```typescript const controller = new AbortController(); const timeout = setTimeout(() => controller.abort(), 5000); try { await put('file.txt', data, { access: 'public', abortSignal: controller.signal, }); } catch (error) { if (error instanceof BlobRequestAbortedError) { console.error('Upload was cancelled'); } } finally { clearTimeout(timeout); } ``` -------------------------------- ### Handling BlobNotFoundError Source: https://github.com/vercel/storage/blob/main/_autodocs/blob-errors.md Catch this error when attempting to access a blob that does not exist, for example, when using `head()` or `copy()` on a non-existent file. ```typescript try { const metadata = await head('non-existent.txt'); } catch (error) { if (error instanceof BlobNotFoundError) { console.error('Blob not found'); } } ``` -------------------------------- ### Create Edge Config Client Source: https://github.com/vercel/storage/blob/main/_autodocs/edge-config-client.md Use `createClient` to instantiate an Edge Config client. Pass your Edge Config connection string, typically from `process.env.EDGE_CONFIG`. Optional configuration options can be provided to control caching and error handling. ```typescript import { createClient } from '@vercel/edge-config'; const handler: VercelFunction = async (request) => { const edgeConfig = createClient(process.env.EDGE_CONFIG); const featureFlags = await edgeConfig.get('featureFlags'); if (!featureFlags) { return new Response('Feature flags not found', { status: 404, }); } return Response.json(featureFlags); }; ``` -------------------------------- ### createClient Source: https://github.com/vercel/storage/blob/main/_autodocs/edge-config-client.md Creates a new EdgeConfigClient instance. You can use the default client bound to `process.env.EDGE_CONFIG` or create custom clients for different Edge Configs. ```APIDOC ## createClient() ### Description Creates a new EdgeConfigClient instance. You can use the default client bound to `process.env.EDGE_CONFIG` or create custom clients for different Edge Configs. ### Signature ```typescript export function createClient(connectionString: string | undefined, options?: EdgeConfigClientOptions): EdgeConfigClient ``` ### Parameters #### connectionString - **Type**: `string | undefined` - **Required**: Yes - **Description**: Edge Config connection string (usually from `process.env.EDGE_CONFIG`) #### options - **Type**: `EdgeConfigClientOptions` - **Required**: No - **Default**: `{ cache: 'no-store', staleIfError: 604800 }` - **Description**: Configuration options for the client. ##### EdgeConfigClientOptions - **cache**: ('no-store' | 'force-cache') - Optional - Fetch cache mode. Use 'force-cache' for static pages in Next.js. - **staleIfError**: (number) - Optional - Stale-if-error cache duration in seconds (1 week default). - **disableDevelopmentCache**: (boolean) - Optional - Disable SWR cache in development mode. ### Return Type ```typescript interface EdgeConfigClient { connection: Connection; get(key: string, options?: EdgeConfigFunctionsOptions): Promise; getAll(keys?: (keyof T)[], options?: EdgeConfigFunctionsOptions): Promise; has(key: string, options?: EdgeConfigFunctionsOptions): Promise; digest(options?: EdgeConfigFunctionsOptions): Promise; } ``` ``` -------------------------------- ### List All Blobs with Pagination Source: https://github.com/vercel/storage/blob/main/_autodocs/blob-list.md Iterates through all blobs in the store, calculating total size, file count, and statistics by file type. Use this for comprehensive storage analysis. ```typescript import { list } from '@vercel/blob'; async function analyzeStorage() { let totalSize = 0; let totalFiles = 0; const typeStats = {}; let cursor; let hasMore = true; while (hasMore) { const { blobs, cursor: nextCursor, hasMore: more } = await list({ limit: 1000, cursor, }); for (const blob of blobs) { totalSize += blob.size; totalFiles++; const ext = blob.pathname.split('.').pop() || 'unknown'; typeStats[ext] = (typeStats[ext] || 0) + 1; } cursor = nextCursor; hasMore = more; } console.log(`Total: ${totalFiles} files, ${(totalSize / 1024 / 1024 / 1024).toFixed(2)} GB`); console.log('By type:', typeStats); } await analyzeStorage(); ``` -------------------------------- ### Get Edge Config Digest Source: https://github.com/vercel/storage/blob/main/_autodocs/edge-config-client.md Obtain the digest of the Edge Config data. This can be used to check if the configuration has changed since the last retrieval. ```typescript import { createClient } from '@vercel/edge-config'; const handler: VercelFunction = async (request) => { const edgeConfig = createClient(process.env.EDGE_CONFIG); const digest = await edgeConfig.digest(); return Response.json({ digest }); }; ``` -------------------------------- ### Preventing Mutations with Frozen Values Source: https://github.com/vercel/storage/blob/main/_autodocs/edge-config-configuration.md Values from `get()` and `getAll()` are frozen for performance. Use `clone()` to create a mutable copy if modifications are needed. ```typescript import { get, clone } from '@vercel/edge-config'; const config = await get<{ timeout: number }>('settings'); config.timeout = 100; // Error: Cannot assign to read only property // Use clone() to make mutable const mutable = clone(config); mutable.timeout = 100; // OK ``` -------------------------------- ### Vercel Blob SDK: Upload, Retrieve, and Delete Source: https://github.com/vercel/storage/blob/main/_autodocs/README.md Demonstrates basic file operations using the Vercel Blob SDK. Use this for uploading, downloading, and removing files from Vercel Blob storage. ```typescript import { put, get, del } from '@vercel/blob'; // Upload const blob = await put('documents/file.pdf', fileBuffer, { access: 'public', }); console.log(blob.url); // Retrieve const result = await get('documents/file.pdf', { access: 'public', }); if (result?.statusCode === 200) { // Process stream... } // Delete await del('documents/file.pdf'); ``` -------------------------------- ### Get Blob Result Source: https://github.com/vercel/storage/blob/main/_autodocs/blob-get.md The result of a `getBlob` operation can be a successful response with blob data, a 304 Not Modified response, or null if the blob does not exist. ```APIDOC ## Get Blob ### Description Retrieves a blob from Vercel Storage. Returns `null` if the blob does not exist (404). ### Return Type ```typescript type GetBlobResult = | { statusCode: 200; stream: ReadableStream; headers: Headers; blob: { url: string; downloadUrl: string; pathname: string; contentType: string; contentDisposition: string; cacheControl: string; uploadedAt: Date; size: number; etag: string; }; } | { statusCode: 304; stream: null; headers: Headers; blob: { url: string; downloadUrl: string; pathname: string; contentType: null; contentDisposition: string; cacheControl: string; uploadedAt: Date; size: null; etag: string; }; } | null ``` ### Status Codes - **200 OK**: Blob found and returned with its content and metadata. - `stream`: ReadableStream of blob content. - `blob.contentType`: MIME type of the blob. - `blob.size`: Content length in bytes. - `blob.etag`: Current ETag for future conditional requests. - **304 Not Modified**: Blob has not changed since the `ifNoneMatch` ETag was provided. - `stream`: null (no body to stream). - `blob.contentType`: null. - `blob.size`: null. - **404 Not Found**: Blob does not exist. The function returns `null` in this case. ### Errors Thrown - **BlobError**: Missing pathname/URL, invalid options, or URL doesn't point to blob.vercel-storage.com. - **BlobAccessError**: Invalid or missing token for private blob. - **BlobNotFoundError**: Blob doesn't exist (returns null instead). - **BlobStoreNotFoundError**: Blob store does not exist. - **BlobStoreSuspendedError**: Blob store is suspended. - **BlobServiceRateLimited**: Too many concurrent requests. - **BlobServiceNotAvailable**: Service temporarily unavailable. ```