### Install Dependencies and Start Development Server Source: https://github.com/netlify/primitives/blob/main/packages/vite-plugin-tanstack-start/test/fixtures/start-basic-rc/README.md Install project dependencies using pnpm and start the development server. The server rebuilds assets automatically on file changes. ```sh pnpm install pnpm dev ``` -------------------------------- ### Start New Project with TanStack Router Basic Example Source: https://github.com/netlify/primitives/blob/main/packages/vite-plugin-tanstack-start/test/fixtures/start-basic-rc/README.md Use this command to initialize a new project based on the TanStack Router basic example. ```sh npx gitpick TanStack/router/tree/main/examples/react/start-basic start-basic ``` -------------------------------- ### Start Nuxt Development Server Source: https://github.com/netlify/primitives/blob/main/packages/nuxt-module/README.md After installing the module, simply start your Nuxt development server to have Netlify platform emulation active. No further configuration is needed. ```bash npx nuxt dev ``` -------------------------------- ### Install @netlify/vite-plugin-tanstack-start Source: https://github.com/netlify/primitives/blob/main/packages/vite-plugin-tanstack-start/README.md Install the plugin as a development dependency using npm. ```bash npm install -D @netlify/vite-plugin-tanstack-start ``` -------------------------------- ### Install @netlify/functions Source: https://github.com/netlify/primitives/blob/main/packages/functions/prod/README.md Install the Netlify Functions primitives package using npm. ```bash npm install @netlify/functions ``` -------------------------------- ### Install @netlify/dev with npm Source: https://github.com/netlify/primitives/blob/main/packages/dev/README.md Use this command to install the @netlify/dev package using npm. ```bash npm install @netlify/dev ``` -------------------------------- ### Emulate Netlify Runtime with @netlify/dev Source: https://github.com/netlify/primitives/blob/main/packages/dev/README.md This TypeScript example demonstrates how to use NetlifyDev to emulate the Netlify runtime locally. It shows how to configure features like blobs, edge functions, environment variables, functions, redirects, and static files. The example also includes starting the server, handling a request, and stopping the server. ```typescript import { NetlifyDev } from '@netlify/dev' const devServer = new NetlifyDev({ blobs: { enabled: true }, edgeFunctions: { enabled: true }, environmentVariables: { enabled: true }, functions: { enabled: true }, redirects: { enabled: true }, staticFiles: { enabled: true, // OPTIONAL: additional directories containing static files to serve // Your `projectRoot` (see below) and your site's `publish` dir are served by default directories: ['public'], }, // OPTIONAL: base dir (https://docs.netlify.com/configure-builds/overview/#definitions) // Defaults to current working directory projectRoot: 'site', // OPTIONAL: if your local dev setup has its own HTTP server (e.g. Vite), set its address here serverAddress: 'http://localhost:1234', }) await devServer.start() const response = await devServer.handle(new Request('http://localhost:8888/path'), { // An optional callback that will be called with every header (key and value) coming from header rules. // See https://docs.netlify.com/routing/headers/ headersCollector: (key: string, value: string) => console.log(key, value), }) console.log(await response.text()) await devServer.stop() ``` -------------------------------- ### Install Project Dependencies Source: https://github.com/netlify/primitives/blob/main/packages/blobs/CONTRIBUTING.md Run this command in your terminal to install all necessary project dependencies after cloning the repository. ```bash npm install ``` -------------------------------- ### Install @netlify/dev with yarn Source: https://github.com/netlify/primitives/blob/main/packages/dev/README.md Use this command to install the @netlify/dev package using yarn. ```bash yarn add @netlify/dev ``` -------------------------------- ### Install Netlify Nuxt Module Source: https://github.com/netlify/primitives/blob/main/packages/nuxt-module/README.md Install the @netlify/nuxt module to enable Netlify platform emulation in your Nuxt application. This setup is automatic once installed. ```bash npx nuxi module add @netlify/nuxt ``` -------------------------------- ### Test Project Setup Source: https://github.com/netlify/primitives/blob/main/packages/blobs/CONTRIBUTING.md Execute this command to verify that the project has been set up correctly and all tests pass. ```bash npm test ``` -------------------------------- ### Install @netlify/cache Source: https://github.com/netlify/primitives/blob/main/packages/cache/README.md Install the @netlify/cache package using npm. This is the first step to using the Netlify cache utilities. ```shell npm install @netlify/cache ``` -------------------------------- ### Install @netlify/otel via npm Source: https://github.com/netlify/primitives/blob/main/packages/otel/README.md Use this command to install the @netlify/otel package using npm. ```shell npm install @netlify/otel ``` -------------------------------- ### Initialize and Use BlobsServer Source: https://github.com/netlify/primitives/blob/main/packages/blobs/README.md This snippet demonstrates how to create a `BlobsServer` instance, start it, and then initialize a store that connects to this local server. ```APIDOC ## Initialize and Use BlobsServer ### Description This example shows how to set up a local Netlify Blobs server using the `BlobsServer` class and then interact with it using the `getStore` function. ### Method N/A (This is a programmatic example, not a direct HTTP request) ### Endpoint N/A (This example focuses on client-side initialization and server setup) ### Parameters #### Server Initialization (BlobsServer constructor) - **directory** (string) - Required - The local directory path where blobs and metadata will be persisted. - **port** (number) - Optional - The port number for the local server to listen on. Defaults to a system-chosen port if not specified. - **token** (string) - Required - A token for protecting your local server from extraneous requests. #### Store Initialization (getStore function) - **edgeURL** (string) - Required - The URL of the local server (e.g., 'http://localhost:1234'). - **name** (string) - Required - The name of the store. - **token** (string) - Required - The authentication token for the server. ### Request Example ```ts import { BlobsServer, getStore } from '@netlify/blobs' // Choose any token for protecting your local server from // extraneous requests const token = 'some-token' // Create a server by providing a local directory where all // blobs and metadata should be persisted const server = new BlobsServer({ directory: '/path/to/blobs/directory', port: 1234, token, }) await server.start() // Get a store and provide the address of the local server const store = getStore({ edgeURL: 'http://localhost:1234', name: 'my-store', token, }) await store.set('my-key', 'This is a local blob') console.log(await store.get('my-key')) ``` ### Response #### Success Response (store.get) - **data** (string | null) - The content of the blob if found, otherwise null. #### Response Example ```json { "data": "This is a local blob" } ``` ``` -------------------------------- ### Install @netlify/types Source: https://github.com/netlify/primitives/blob/main/packages/types/README.md Install the @netlify/types package using npm. Requires Node.js 16.0.0 or above. ```shell npm install @netlify/types ``` -------------------------------- ### Install @netlify/vite-plugin Source: https://github.com/netlify/primitives/blob/main/packages/vite-plugin/README.md Install the plugin using npm. This is the first step before configuring it in your Vite project. ```bash npm install @netlify/vite-plugin ``` -------------------------------- ### Initialize and Start Netlify Local Development Server Source: https://context7.com/netlify/primitives/llms.txt Instantiate `NetlifyDev` to create a local emulator for Netlify's production environment. Configure features like Blobs, Edge Functions, environment variables, functions, Image CDN, redirects, and static file serving. Start the server using `devServer.start()`. ```typescript import { NetlifyDev } from '@netlify/dev' // Create a local development server with all features const devServer = new NetlifyDev({ // Enable Netlify Blobs emulation blobs: { enabled: true }, // Enable Edge Functions edgeFunctions: { enabled: true }, // Load environment variables from Netlify environmentVariables: { enabled: true }, // Enable serverless functions functions: { enabled: true }, // Enable Image CDN emulation images: { enabled: true }, // Enable redirects processing redirects: { enabled: true }, // Configure static file serving staticFiles: { enabled: true, directories: ['public', 'static'] // Additional directories }, // Project configuration projectRoot: process.cwd(), // Optional: proxy to existing dev server (e.g., Vite, Next.js) serverAddress: 'http://localhost:3000', // Custom logger logger: { log: console.log, warn: console.warn, error: console.error } }) // Start the development server await devServer.start() // Handle requests programmatically const response = await devServer.handle( new Request('http://localhost:8888/api/hello'), { // Collect headers from _headers file rules headersCollector: (key, value) => { console.log(`Header rule: ${key}: ${value}`) } } ) console.log(await response.text()) // Check which features are enabled const features = devServer.getEnabledFeatures() console.log('Enabled features:', features) // ['blobs', 'edgeFunctions', 'environmentVariables', 'functions', 'images', 'redirects', 'staticFiles'] // Check if site is linked to Netlify if (!devServer.siteIsLinked) { console.log('Run `netlify init` to link this project') } // Handle Node.js request/response (for middleware integration) const result = await devServer.handleAndIntrospectNodeRequest(nodeRequest, { serverAddress: 'http://localhost:3000', headersCollector: (key, value) => console.log(key, value) }) if (result?.type === 'static') { // Let upstream server handle static files } else if (result) { // Use result.response } // Stop the server await devServer.stop() ``` -------------------------------- ### _headers file format example Source: https://context7.com/netlify/primitives/llms.txt Example format for a Netlify `_headers` file, showing global, API, and static asset header configurations. ```plaintext # Global headers /* X-Frame-Options: DENY X-Content-Type-Options: nosniff # API headers /api/* Access-Control-Allow-Origin: * Cache-Control: no-store # Static assets /static/* Cache-Control: public, max-age=31536000, immutable ``` -------------------------------- ### Install @netlify/aws-lambda-compat Source: https://github.com/netlify/primitives/blob/main/packages/aws-lambda-compat/README.md Install the package using npm. This is the first step to using the AWS Lambda compatibility wrapper. ```shell npm install @netlify/aws-lambda-compat ``` -------------------------------- ### Install @netlify/blobs via npm Source: https://github.com/netlify/primitives/blob/main/packages/blobs/README.md Install the @netlify/blobs package using npm. Ensure your environment meets the Deno or Node.js version requirements. ```shell npm install @netlify/blobs ``` -------------------------------- ### Image CDN Query Parameters and Example URLs Source: https://context7.com/netlify/primitives/llms.txt Lists supported query parameters for image transformations including url, width, height, quality, format, fit, and position. Provides example URLs for common image manipulation tasks. ```plaintext // Supported query parameters: // - url: Source image URL (required) // - w / width: Target width in pixels // - h / height: Target height in pixels // - q / quality: Image quality (1-100) // - fm: Output format (webp, avif, png, jpg) // - fit: Resize fit mode (cover, contain, fill, inside, outside) // - position: Crop position (center, top, bottom, left, right, etc.) // Example URLs: // /.netlify/images?url=/photo.jpg&w=400 // /.netlify/images?url=/photo.jpg&w=800&h=600&fit=cover // /.netlify/images?url=/photo.jpg&q=75&fm=webp // /.netlify/images?url=https://images.unsplash.com/photo-xxx&w=1200 // Remote images must match patterns in remote_images config // Local images are served from the origin server ``` -------------------------------- ### Configure Plugin Options Source: https://github.com/netlify/primitives/blob/main/packages/vite-plugin-tanstack-start/README.md Example of configuring the plugin with specific options for the development environment, such as enabling edge functions. ```typescript { dev: { edgeFunctions: { enabled: false, }, // ... All dev options are supported here. // See https://www.npmjs.com/package/@netlify/vite-plugin. }, } ``` -------------------------------- ### Netlify Function Example Source: https://context7.com/netlify/primitives/llms.txt An example function that can be used with the @netlify/vite-plugin. It returns a JSON response with a message and the request URL. ```typescript // Example function that works with the plugin // netlify/functions/hello.ts export default async (request: Request) => { return new Response(JSON.stringify({ message: 'Hello from Netlify Function!', url: request.url }), { headers: { 'Content-Type': 'application/json' } }) } ``` -------------------------------- ### Local Development Commands for Netlify Nuxt Source: https://github.com/netlify/primitives/blob/main/packages/nuxt-module/README.md Commands for local development, including installing dependencies, generating type stubs, building, and linting the Netlify Nuxt package. ```bash npm install ``` ```bash npm run dev:prepare ``` ```bash npm run dev ``` ```bash npm run dev:build ``` ```bash npm run lint ``` ```bash npm run test ``` ```bash npm run test:watch ``` -------------------------------- ### Get Store with Environment Configuration Source: https://github.com/netlify/primitives/blob/main/packages/blobs/README.md Obtain a store reference using environment variables for configuration. This is useful when configuration is managed externally. ```typescript import { getStore } from '@netlify/blobs' const store = getStore('my-store') console.log(await store.get('my-key')) ``` -------------------------------- ### Get Store with Custom Fetch Implementation Source: https://github.com/netlify/primitives/blob/main/packages/blobs/README.md Configure the `getStore` method with a custom `fetch` implementation. This allows you to control the HTTP client used by the Netlify Blobs library. Requires `whatwg-fetch`. ```typescript import { fetch } from 'whatwg-fetch' import { getStore } from '@netlify/blobs' const store = getStore({ fetch, name: 'my-store', }) console.log(await store.get('my-key')) ``` -------------------------------- ### Get Store with API Access Configuration Source: https://github.com/netlify/primitives/blob/main/packages/blobs/README.md Create a store instance for API access by providing explicit configuration details including site ID and a personal access token. This method ensures strong consistency. ```typescript import { getStore } from '@netlify/blobs' const store = getStore({ name: 'my-store', siteID: 'MY_SITE_ID', token: 'MY_TOKEN', }) console.log(await store.get('some-key')) ``` -------------------------------- ### Redirects and Rewrites File Format Examples Source: https://context7.com/netlify/primitives/llms.txt Illustrates various formats for Netlify redirects and rewrites, including simple redirects, rewrites (proxy), SPA fallbacks, conditional redirects by country, role-based redirects, and signed redirects. ```plaintext # Simple redirect /old-page /new-page 301 # Rewrite (proxy) /api/* https://api.example.com/:splat 200 # SPA fallback /* /index.html 200 # Conditional redirect based on country /pricing /pricing/eu 302 Country=de,fr,it,es # Role-based redirect (requires JWT) /admin/* /login 302 Role=admin # Signed redirect for secure proxying /secure/* https://protected.example.com/:splat 200 signed ``` -------------------------------- ### Get Store with Edge Access Configuration Source: https://github.com/netlify/primitives/blob/main/packages/blobs/README.md Configure a store for edge access using the `edgeURL` and an access token. This provides fast, eventually consistent reads across multiple locations. ```typescript import { Buffer } from 'node:buffer' import { getStore } from '@netlify/blobs' // Serverless function using the Lambda compatibility mode export const handler = async (event) => { const rawData = Buffer.from(event.blobs, 'base64') const data = JSON.parse(rawData.toString('ascii')) const store = getStore({ edgeURL: data.url, name: 'my-store', token: data.token, siteID: 'MY_SITE_ID', }) const item = await store.get('some-key') return { statusCode: 200, body: item, } } ``` -------------------------------- ### Distributed Tracing with @netlify/otel Source: https://context7.com/netlify/primitives/llms.txt Utilize @netlify/otel for distributed tracing. Get a tracer instance and use withActiveSpan to create spans with attributes. Ensure graceful shutdown by handling SIGTERM. ```typescript import { getTracer, withActiveSpan, shutdownTracers } from '@netlify/otel' // Get a tracer instance (returns undefined if not configured) const tracer = getTracer('my-service', '1.0.0') if (tracer) { // Create spans for tracing const result = withActiveSpan(tracer, 'fetch-user-data', async (span) => { span?.setAttributes({ 'user.id': '123', 'operation.type': 'database-query' }) const user = await fetchUser('123') span?.setAttributes({ 'user.found': !!user }) return user }) // With options withActiveSpan( tracer, 'process-order', { attributes: { 'order.type': 'subscription' } }, async (span) => { // Processing logic } ) } // Graceful shutdown process.on('SIGTERM', async () => { await shutdownTracers() process.exit(0) }) ``` -------------------------------- ### Get Deploy Store with Environment Configuration Source: https://github.com/netlify/primitives/blob/main/packages/blobs/README.md Use `getDeployStore` without explicit parameters to leverage environment-based configuration for a deploy-scoped store. Asserts that data set in a previous step is retrievable. ```typescript // Using environment-based configuration const store2 = getDeployStore() assert.equal(await store2.get('my-key'), 'my value') ``` -------------------------------- ### Store API Reference - get Source: https://github.com/netlify/primitives/blob/main/packages/blobs/README.md Retrieves an object with the given key. Supports various return types and returns null if the key is not found. ```APIDOC ## `get(key: string, { type?: string }): Promise` Retrieves an object with the given key. ### Parameters - **key** (string) - Required - The key of the object to retrieve. - **options** (object) - Optional - Configuration for the retrieval. - **type** (string) - Optional - The desired format of the returned entry. Possible values: - `arrayBuffer`: Returns the entry as an `ArrayBuffer`. - `blob`: Returns the entry as a `Blob`. - `json`: Parses the entry as JSON and returns the resulting object. - `stream`: Returns the entry as a `ReadableStream`. - `text` (default): Returns the entry as a string of plain text. If an object with the given key is not found, `null` is returned. ### Request Example ```javascript const entry = await store.get('some-key', { type: 'json' }) console.log(entry) ``` ``` -------------------------------- ### Get JSON Entry from Store Source: https://github.com/netlify/primitives/blob/main/packages/blobs/README.md Retrieves an entry from the store and parses it as JSON. If the key is not found, `null` is returned. Ensure the stored data is valid JSON. ```javascript const entry = await store.get('some-key', { type: 'json' }) console.log(entry) ``` -------------------------------- ### Get Deploy Store with API Token Source: https://github.com/netlify/primitives/blob/main/packages/blobs/README.md Use `getDeployStore` to create a store scoped to a specific deploy. This is useful for data that should be managed by the platform and deleted when the deploy is removed. Requires API access token. ```typescript import { assert } from 'node:assert' import { getDeployStore } from '@netlify/blobs' // Using API access const store1 = getDeployStore({ deployID: 'MY_DEPLOY_ID', token: 'MY_API_TOKEN', }) await store1.set('my-key', 'my value') ``` -------------------------------- ### List blobs with a prefix filter Source: https://github.com/netlify/primitives/blob/main/packages/blobs/README.md Filter the list of blobs by providing a `prefix` option to the `list` method. Only entries whose keys start with the specified prefix will be returned. ```javascript const { blobs } = await store.list({ prefix: 'some' }) // [ { etag: 'etag1', key: 'some-key' } ] console.log(blobs) ``` -------------------------------- ### Get Entry with Metadata Source: https://github.com/netlify/primitives/blob/main/packages/blobs/README.md Retrieves an entry along with its ETag and any associated metadata. The `type` parameter can be used to specify the desired return format, defaulting to text. Returns `null` if the key is not found. ```javascript const blob = await store.getWithMetadata('some-key', { type: 'json' }) console.log(blob.data, blob.etag, blob.metadata) ``` -------------------------------- ### Get Metadata for a Key Source: https://github.com/netlify/primitives/blob/main/packages/blobs/README.md Retrieves only the ETag and metadata for a given key without fetching the actual blob data. Returns `null` if the key is not found. Useful for checking existence or changes efficiently. ```javascript const blob = await store.getMetadata('some-key') console.log(blob.etag, blob.metadata) ``` -------------------------------- ### Initialize and Use Local Netlify Blobs Server Source: https://github.com/netlify/primitives/blob/main/packages/blobs/README.md Use this snippet to create a local Netlify Blobs server for testing. Ensure you provide a directory for blob persistence and a token for security. You can then initialize a store pointing to this local server. ```typescript import { BlobsServer, getStore } from '@netlify/blobs' // Choose any token for protecting your local server from // extraneous requests const token = 'some-token' // Create a server by providing a local directory where all // blobs and metadata should be persisted const server = new BlobsServer({ directory: '/path/to/blobs/directory', port: 1234, token, }) await server.start() // Get a store and provide the address of the local server const store = getStore({ edgeURL: 'http://localhost:1234', name: 'my-store', token, }) await store.set('my-key', 'This is a local blob') console.log(await store.get('my-key')) ``` -------------------------------- ### Build Project for Production Source: https://github.com/netlify/primitives/blob/main/packages/vite-plugin-tanstack-start/test/fixtures/start-basic-rc/README.md Compile the project for production deployment using the pnpm build command. ```sh pnpm build ``` -------------------------------- ### Build All Packages Source: https://github.com/netlify/primitives/blob/main/README.md Execute this command to build all packages within the monorepo. ```sh npm run build --workspaces=true ``` -------------------------------- ### Serve Static Files with @netlify/static Source: https://context7.com/netlify/primitives/llms.txt Use StaticHandler to serve static files. Configure with a directory or array of directories. The handler automatically resolves index.html, sets Content-Type, and supports streaming responses. ```typescript import { StaticHandler } from '@netlify/static' // Create a static file handler const staticHandler = new StaticHandler({ directory: ['dist', 'public'] // Can be a single path or array }) // Match requests against static files const request = new Request('http://localhost:8888/styles/main.css') const match = await staticHandler.match(request) if (match) { // Serve the static file const response = await match.handle() console.log('Status:', response.status) // 200 console.log('Content-Type:', response.headers.get('content-type')) // text/css console.log('Cache-Control:', response.headers.get('cache-control')) // public, max-age=0, must-revalidate } ``` -------------------------------- ### Connect Lambda for Environment Configuration Source: https://github.com/netlify/primitives/blob/main/packages/blobs/README.md Initialize the Netlify Blobs environment for Lambda compatibility mode by calling `connectLambda` with the Lambda event. This must be done before calling `getStore` or `getDeployStore`. ```typescript import { connectLambda, getStore } from '@netlify/blobs' export const handler = async (event) => { connectLambda(event) const store = getStore('my-store') const value = await store.get('my-key') return { statusCode: 200, body: value, } } ``` -------------------------------- ### Custom Fetch Configuration Source: https://github.com/netlify/primitives/blob/main/packages/blobs/README.md Explains how to provide a custom `fetch` implementation to the `getStore` method for controlling HTTP calls. ```APIDOC ## Custom `fetch` The client uses the web platform `fetch()` to make HTTP calls. By default, it will use any globally-defined instance of `fetch`, but you can choose to provide your own by supplying a `fetch` property to the `getStore` method. ### API Usage ```ts import { fetch } from 'whatwg-fetch' import { getStore } from '@netlify/blobs' const store = getStore({ fetch: fetch, name: 'my-store', }) console.log(await store.get('my-key')) ``` ``` -------------------------------- ### Deploy Scope Store Source: https://github.com/netlify/primitives/blob/main/packages/blobs/README.md Demonstrates how to create and use a deploy-scoped store, where data is managed by the platform and tied to the lifecycle of a deploy. ```APIDOC ## Deploy Scope Store By default, stores exist at the site level. However, you can opt-in to deploy-scoped storage by creating the store using the `getDeployStore` method. This means data is kept as long as the deploy is around and wiped if the deploy is deleted. ### API Usage ```ts import { getDeployStore } from '@netlify/blobs' // Using API access const store1 = getDeployStore({ deployID: 'MY_DEPLOY_ID', token: 'MY_API_TOKEN', }) await store1.set('my-key', 'my value') // Using environment-based configuration const store2 = getDeployStore() assert.equal(await store2.get('my-key'), 'my value') ``` ``` -------------------------------- ### Configure Vite with @netlify/vite-plugin Source: https://github.com/netlify/primitives/blob/main/packages/vite-plugin/README.md Add the Netlify Vite plugin to your Vite configuration file. Ensure you import it correctly. ```javascript import { defineConfig } from 'vite' import netlify from '@netlify/vite-plugin' export default defineConfig({ plugins: [netlify()], }) ``` -------------------------------- ### Initialize @netlify/headers HeadersHandler Source: https://context7.com/netlify/primitives/llms.txt Initialize the HeadersHandler with project and publish directories, optional config path, programmatic headers, and a logger. The handler watches for `_headers` files. ```typescript import { HeadersHandler } from '@netlify/headers' // Create a headers handler const headersHandler = new HeadersHandler({ projectDir: process.cwd(), publishDir: 'dist', configPath: 'netlify.toml', // Optional configHeaders: [ // Optional programmatic headers { for: '/api/*', values: { 'Access-Control-Allow-Origin': '*', 'Cache-Control': 'no-store' } } ], logger: console }) // Get the paths being watched for _headers files console.log(headersHandler.headersFiles) // ['/project/_headers', '/project/dist/_headers'] ``` -------------------------------- ### Create and Use Image Handler Source: https://context7.com/netlify/primitives/llms.txt Instantiate an ImageHandler with image configuration, then match requests to the image CDN endpoint. Handles image transformations like resizing and format conversion. ```typescript import { ImageHandler } from '@netlify/images' // Create an image handler const imageHandler = new ImageHandler({ logger: console, imagesConfig: { remote_images: [ '^https://images\.unsplash\.com/.*', '^https://cdn\.example\.com/.*' ] } }) // Match requests to the image CDN endpoint const request = new Request( 'http://localhost:8888/.netlify/images?url=/hero.jpg&w=800&h=600&q=80&fm=webp' ) const match = imageHandler.match(request) if (match) { // Handle the image transformation const response = await match.handle('http://localhost:3000') console.log('Content-Type:', response.headers.get('content-type')) // image/webp (if fm=webp was specified) } ``` -------------------------------- ### Integrate Plugin in Vite Configuration Source: https://github.com/netlify/primitives/blob/main/packages/vite-plugin-tanstack-start/README.md Add the `@netlify/vite-plugin-tanstack-start` plugin to your `vite.config.js` or `vite.config.ts` file alongside other Vite plugins. ```javascript import { defineConfig } from 'vite' import { tanstackStart } from '@tanstack/react-start/plugin/vite' import react from '@vitejs/plugin-react' import netlify from '@netlify/vite-plugin-tanstack-start' export default defineConfig({ plugins: [tanstackStart(), react(), netlify()], }) ``` -------------------------------- ### List blobs hierarchically with directories Source: https://github.com/netlify/primitives/blob/main/packages/blobs/README.md Enable hierarchical listing by setting the `directories` option to `true` in the `list` method. This groups blobs into directories based on the '/' character in their keys. ```javascript const { blobs, directories } = await store.list({ directories: true }) // [ { etag: "etag1", key: "pink-panther.jpg" } ] console.log(blobs) // [ "cats", "mice" ] console.log(directories) ``` -------------------------------- ### Publish Package Source: https://github.com/netlify/primitives/blob/main/packages/blobs/CONTRIBUTING.md This command is used to publish the package to the npm registry after merging release PRs and switching to the default branch. ```bash npm publish ``` -------------------------------- ### Develop with Auto-Rebuild Source: https://github.com/netlify/primitives/blob/main/README.md Use this command for continuous development, enabling packages to rebuild automatically on changes. ```sh npm run dev ``` -------------------------------- ### Basic Blob Storage Operations with @netlify/blobs Source: https://context7.com/netlify/primitives/llms.txt Demonstrates fundamental operations for storing, retrieving, and deleting data using the @netlify/blobs client. Supports JSON data with metadata and conditional writes. ```typescript import { getStore, getDeployStore, listStores, connectLambda, BlobsServer } from '@netlify/blobs' // Basic store operations with environment-based configuration const store = getStore('my-store') // Store and retrieve text data await store.set('user:123', 'John Doe') const userName = await store.get('user:123') console.log(userName) // "John Doe" // Store JSON data with metadata await store.setJSON('config:app', { theme: 'dark', version: '2.0' }, { metadata: { updatedBy: 'admin', timestamp: Date.now() } }) // Retrieve JSON with metadata and ETag for conditional requests const result = await store.getWithMetadata('config:app', { type: 'json' }) console.log(result.data) // { theme: 'dark', version: '2.0' } console.log(result.etag) // "abc123..." console.log(result.metadata) // { updatedBy: 'admin', timestamp: ... } // Conditional write - only if key doesn't exist const writeResult = await store.set('unique-key', 'value', { onlyIfNew: true }) if (!writeResult.modified) { console.log('Key already exists, write skipped') } // Conditional write - only if ETag matches (optimistic locking) const updateResult = await store.set('config:app', 'new-value', { onlyIfMatch: result.etag }) // Retrieve data in different formats const binaryData = await store.get('image.png', { type: 'arrayBuffer' }) const blobData = await store.get('document.pdf', { type: 'blob' }) const streamData = await store.get('large-file.zip', { type: 'stream' }) // List blobs with prefix filtering const { blobs } = await store.list({ prefix: 'user:' }) for (const blob of blobs) { console.log(`Key: ${blob.key}, ETag: ${blob.etag}`) } // Hierarchical listing with directories const { blobs: files, directories } = await store.list({ directories: true, prefix: 'uploads/' }) console.log('Directories:', directories) // ['uploads/images', 'uploads/docs'] console.log('Files:', files) // Paginated listing for large stores for await (const page of store.list({ paginate: true })) { console.log(`Page with ${page.blobs.length} blobs`) } // Delete operations await store.delete('user:123') const deleteResult = await store.deleteAll() // Delete entire store console.log(`Deleted ${deleteResult.deletedBlobs} blobs`) // Deploy-scoped store (data tied to specific deploy) const deployStore = getDeployStore({ deployID: 'deploy-abc123', token: 'MY_API_TOKEN' }) await deployStore.set('build-cache', 'cached-data') // API access with explicit configuration const apiStore = getStore({ name: 'my-store', siteID: 'site-123', token: 'MY_NETLIFY_TOKEN', apiURL: 'https://api.netlify.com' }) // Edge access for fast reads (eventually consistent) const edgeStore = getStore({ name: 'my-store', siteID: 'site-123', token: 'edge-token', edgeURL: 'https://edge.netlify.com' }) // Lambda compatibility mode export const handler = async (event) => { connectLambda(event) // Initialize environment from Lambda event const store = getStore('my-store') const value = await store.get('key') return { statusCode: 200, body: value } } // List all stores in a site const stores = await listStores({ siteID: 'site-123', token: 'token' }) console.log(stores) // ['store1', 'store2'] // Local development server for testing const server = new BlobsServer({ directory: '/tmp/blobs', port: 8888, token: 'dev-token', debug: true, onRequest: ({ type, url }) => console.log(`${type}: ${url}`) }) await server.start() const testStore = getStore({ name: 'test-store', edgeURL: 'http://localhost:8888', token: 'dev-token', siteID: 'local-site' }) await testStore.set('test-key', 'test-value') console.log(await testStore.get('test-key')) // "test-value" await server.stop() ``` -------------------------------- ### Configure @netlify/vite-plugin Source: https://context7.com/netlify/primitives/llms.txt Configure the Vite plugin with various Netlify features enabled or disabled. Uses defaults when no options are provided. ```typescript // vite.config.ts import { defineConfig } from 'vite' import netlify from '@netlify/vite-plugin' export default defineConfig({ plugins: [ netlify({ // Enable/disable the middleware (default: true) middleware: true, // Configure individual features blobs: { enabled: true }, edgeFunctions: { enabled: true }, environmentVariables: { enabled: true }, functions: { enabled: true }, images: { enabled: true }, redirects: { enabled: true }, staticFiles: { enabled: true, directories: ['public'] } }) ] }) // Minimal configuration - uses defaults export default defineConfig({ plugins: [netlify()] }) // Disable middleware but keep environment loading export default defineConfig({ plugins: [ netlify({ middleware: false, // Don't intercept requests environmentVariables: { enabled: true } }) ] }) ``` -------------------------------- ### List all blobs in the store Source: https://github.com/netlify/primitives/blob/main/packages/blobs/README.md The `list` method retrieves all blobs stored. The result includes an array of `BlobResult` objects, each containing an `etag` and `key`. This method can return an `AsyncIterable` for paginated results. ```javascript const { blobs } = await store.list() // [ { etag: 'etag1', key: 'some-key' }, { etag: 'etag2', key: 'another-key' } ] console.log(blobs) ``` -------------------------------- ### List blobs within a specific directory Source: https://github.com/netlify/primitives/blob/main/packages/blobs/README.md To list entries within a specific directory, use the directory name as the `prefix` along with the `directories: true` option. A trailing slash in the prefix ensures only direct children are matched. ```javascript const { blobs, directories } = await store.list({ directories: true, prefix: 'cats/' }) // [ { etag: "etag1", key: "cats/garfield.jpg" }, { etag: "etag2", key: "cats/tom.jpg" } ] console.log(blobs) // [ ] console.log(directories) ``` -------------------------------- ### Create and Use Redirects Handler Source: https://context7.com/netlify/primitives/llms.txt Instantiate a RedirectsHandler with project configuration and then match requests against defined redirect rules. Handles SPA fallbacks and geo-based redirects. ```typescript import { RedirectsHandler } from '@netlify/redirects' // Create a redirects handler const redirectsHandler = new RedirectsHandler({ projectDir: process.cwd(), publicDir: 'dist', configPath: 'netlify.toml', configRedirects: [ { from: '/old-path', to: '/new-path', status: 301 }, { from: '/api/*', to: 'https://api.example.com/:splat', status: 200 }, { from: '/app/*', to: '/index.html', status: 200 } // SPA fallback ], geoCountry: 'US', // For geo-based redirects jwtSecret: process.env.JWT_SECRET || '', jwtRoleClaim: 'app_metadata.roles', siteID: 'site-123', siteURL: 'https://example.com' }) // Match a request against redirect rules const request = new Request('https://example.com/old-path') const match = await redirectsHandler.match(request) if (match) { console.log('Match found:') console.log(' Target:', match.target.href) console.log(' Status:', match.statusCode) console.log(' Is redirect:', match.redirect) console.log(' Is external:', match.external) console.log(' Force:', match.force) console.log(' Headers:', match.headers) } // Handle the redirect/rewrite const getStaticFile = async (req: Request) => { // Return a function that serves the static file if it exists const filePath = new URL(req.url).pathname if (await fileExists(filePath)) { return () => serveFile(filePath) } return undefined } const response = await redirectsHandler.handle(request, match, getStaticFile) if (response) { // Response from redirect/rewrite console.log('Response status:', response.status) } ``` -------------------------------- ### Wrap Handler with Builder (JavaScript) Source: https://github.com/netlify/primitives/blob/main/packages/functions/prod/README.md Use the `builder` function to wrap your Netlify Function handler in JavaScript for On-demand Builders. ```javascript const { builder } = require('@netlify/functions') const handler = async (event, context) => { return { statusCode: 200, body: JSON.stringify({ message: 'Hello World' }), } } exports.handler = builder(handler) ``` -------------------------------- ### Store API Reference - getWithMetadata Source: https://github.com/netlify/primitives/blob/main/packages/blobs/README.md Retrieves an object with the given key, its ETag, and any associated metadata. Supports conditional requests using ETag. ```APIDOC ## `getWithMetadata(key: string, { etag?: string, type?: string }): Promise<{ data: any, etag: string, metadata: object }> ` Retrieves an object with the given key, the ETag value for the entry, and any metadata stored with the entry. ### Parameters - **key** (string) - Required - The key of the object to retrieve. - **options** (object) - Optional - Configuration for the retrieval. - **etag** (string) - Optional - The ETag value for conditional requests. If provided, the blob is only returned if it differs from this ETag. - **type** (string) - Optional - The desired format of the returned entry. Possible values: - `arrayBuffer`: Returns the entry as an `ArrayBuffer`. - `blob`: Returns the entry as a `Blob`. - `json`: Parses the entry as JSON and returns the resulting object. - `stream`: Returns the entry as a `ReadableStream`. - `text` (default): Returns the entry as a string of plain text. If an object with the given key is not found, `null` is returned. ### Request Example ```javascript const blob = await store.getWithMetadata('some-key', { type: 'json' }) console.log(blob.data, blob.etag, blob.metadata) ``` ### Conditional Request Example ```javascript // Mock implementation of a system for locally persisting blobs and their etags const cachedETag = getFromMockCache('my-key') // Get entry from the blob store only if its ETag is different from the one you // have locally, which means the entry has changed since you last obtained it const { data, etag } = await store.getWithMetadata('some-key', { etag: cachedETag }) if (etag === cachedETag) { // `data` is `null` because the local blob is fresh } else { // `data` contains the new blob, store it locally alongside the new ETag writeInMockCache('my-key', data, etag) } ``` ``` -------------------------------- ### Manually paginate through store entries Source: https://github.com/netlify/primitives/blob/main/packages/blobs/README.md To handle pagination manually, set the `paginate` option to `true`. This causes the `list` method to return an `AsyncIterator`, allowing you to process entries page by page. ```javascript const blobs = [] for await (const entry of store.list({ paginate: true })) { blobs.push(...entry.blobs) } // [ // { etag: "etag1", key: "cats/garfield.jpg" }, // { etag: "etag2", key: "cats/tom.jpg" }, // { etag: "etag3", key: "mice/jerry.jpg" }, // { etag: "etag4", key: "mice/mickey.jpg" }, // { etag: "etag5", key: "pink-panther.jpg" }, // ] console.log(blobs) ``` -------------------------------- ### Import Netlify Types Source: https://github.com/netlify/primitives/blob/main/packages/types/README.md Import specific types like 'Context' or 'NetlifyGlobal' from the @netlify/types package into your TypeScript code. ```typescript import type { Context } from '@netlify/types' import type { NetlifyGlobal } from '@netlify/types' ``` -------------------------------- ### List Objects Source: https://github.com/netlify/primitives/blob/main/packages/blobs/README.md Retrieves a list of blobs (objects) within the store, with options for filtering and hierarchical listing. ```APIDOC ## GET /store ### Description Returns a list of blobs in a given store. Supports filtering by prefix and hierarchical directory listing. ### Method GET ### Endpoint `/store` ### Parameters #### Query Parameters - **prefix** (string) - Optional - Filters results to keys starting with this prefix. - **directories** (boolean) - Optional - If true, groups results into blobs and directories. - **paginate** (boolean) - Optional - If true, returns an AsyncIterator for paginated results. ### Response #### Success Response (200) - **blobs** (Array) - A list of blob objects, each containing `etag` and `key`. - **directories** (Array) - A list of directory names (only present if `directories` is true). ### Response Example ```json { "blobs": [ { "etag": "etag1", "key": "some-key" }, { "etag": "etag2", "key": "another-key" } ], "directories": ["cats", "mice"] } ``` ``` -------------------------------- ### Basic Netlify Function Handler with TypeScript Source: https://context7.com/netlify/primitives/llms.txt A standard Netlify Function handler using TypeScript types for event and context. Suitable for general-purpose serverless functions. ```typescript import { builder, schedule, stream, purgeCache, type Handler, type HandlerEvent, type HandlerContext } from '@netlify/functions' import { Readable } from 'stream' // Basic function handler with TypeScript types export const handler: Handler = async (event: HandlerEvent, context: HandlerContext) => { const { path, httpMethod, headers, queryStringParameters, body } = event return { statusCode: 200, headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ message: 'Hello from Netlify Functions!', path, method: httpMethod, query: queryStringParameters }) } } ``` -------------------------------- ### Apply Headers with @netlify/headers Source: https://context7.com/netlify/primitives/llms.txt Apply headers to a response based on the request URL using the HeadersHandler. The applied headers are collected in `appliedHeaders`. ```typescript // Apply headers to a response const request = new Request('https://example.com/api/users') const response = new Response('{"users": []}', { headers: { 'Content-Type': 'application/json' } }) // Collect applied headers const appliedHeaders: Record = {} await headersHandler.apply(request, response, (key, value) => { appliedHeaders[key] = value }) console.log(appliedHeaders) // { 'Access-Control-Allow-Origin': '*', 'Cache-Control': 'no-store' } ``` -------------------------------- ### Wrap Handler with Schedule (JavaScript) Source: https://github.com/netlify/primitives/blob/main/packages/functions/prod/README.md Use the `schedule` function to wrap your Netlify Function handler in JavaScript for Scheduled Functions. Specify the cron schedule as the first argument. ```javascript const { schedule } = require('@netlify/functions') exports.handler = schedule('5 4 * * *', async () => { console.log("It's 04:05 AM!") }) ``` -------------------------------- ### Set Object Source: https://github.com/netlify/primitives/blob/main/packages/blobs/README.md Creates or overwrites an object with a given key and value. The value can be a string, ArrayBuffer, or Blob. ```APIDOC ## POST /store ### Description Creates or overwrites an object with the given key and value. ### Method POST ### Endpoint `/store` ### Parameters #### Request Body - **key** (string) - Required - The unique identifier for the object. - **value** (ArrayBuffer | Blob | string) - Required - The content of the object. - **metadata** (object) - Optional - Additional metadata for the object. ### Request Example ```json { "key": "some-key", "value": "This is a string value" } ``` ### Response #### Success Response (200) - **void** - Indicates the operation was successful. #### Response Example (No response body on success) ``` -------------------------------- ### Wrap Handler with Builder (TypeScript) Source: https://github.com/netlify/primitives/blob/main/packages/functions/prod/README.md Use the `builder` function to wrap your Netlify Function handler in TypeScript for On-demand Builders. Ensure you import the `Handler` type. ```typescript import { builder, Handler } from '@netlify/functions' const myHandler: Handler = async (event, context) => { return { statusCode: 200, body: JSON.stringify({ message: 'Hello World' }), } } const handler = builder(myHandler) export { handler } ``` -------------------------------- ### Conditional Fetch with ETag Source: https://github.com/netlify/primitives/blob/main/packages/blobs/README.md Implements conditional fetching by providing a cached ETag. The blob is only returned if its ETag differs from the provided one, indicating a change. Assumes a mock cache implementation for demonstration. ```javascript // Mock implementation of a system for locally persisting blobs and their etags const cachedETag = getFromMockCache('my-key') // Get entry from the blob store only if its ETag is different from the one you // have locally, which means the entry has changed since you last obtained it const { data, etag } = await store.getWithMetadata('some-key', { etag: cachedETag }) if (etag === cachedETag) { // `data` is `null` because the local blob is fresh } else { // `data` contains the new blob, store it locally alongside the new ETag writeInMockCache('my-key', data, etag) } ``` -------------------------------- ### Set a string value in the store Source: https://github.com/netlify/primitives/blob/main/packages/blobs/README.md Use the `set` method to store a string value associated with a key. If the key already exists, its value will be overwritten. ```javascript await store.set('some-key', 'This is a string value') ```