CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-tanstack--react-start

Modern full-stack React framework with SSR, streaming, server functions, and API routes powered by TanStack Router and Vite.

Pending
Overview
Eval results
Files

request-response.mddocs/

Request/Response Utilities

TanStack Start provides utilities for accessing HTTP request information within server functions. These utilities give you access to request data, headers, and client information during server-side execution.

Capabilities

Request Information Functions

Access information about the current HTTP request.

/**
 * Get the current request object
 * @returns Current HTTP request
 */
function getRequest(): Request;

/**
 * Get all request headers
 * @returns Object containing all request headers
 */
function getRequestHeaders(): Record<string, string>;

/**
 * Get a specific request header value
 * @param name - Header name to retrieve
 * @returns Header value or undefined
 */
function getRequestHeader(name: string): string | undefined;

/**
 * Get the client IP address from the request
 * @param options - Options for IP detection
 * @returns Client IP address or undefined
 */
function getRequestIP(options?: { ipHeader?: string }): string | undefined;

Usage Examples:

import {
  getRequest,
  getRequestHeaders,
  getRequestHeader,
  getRequestIP
} from "@tanstack/react-start";

// Access request information in a server function
const getUserInfo = createServerFn()
  .handler(async () => {
    const request = getRequest();
    const headers = getRequestHeaders();
    const userAgent = getRequestHeader("user-agent");
    const clientIP = getRequestIP({ ipHeader: "x-forwarded-for" });

    return {
      method: request.method,
      url: request.url,
      userAgent,
      clientIP,
      headers
    };
  });

// Using request data for authentication
const authenticatedAction = createServerFn()
  .handler(async () => {
    const authHeader = getRequestHeader("authorization");

    if (!authHeader || !authHeader.startsWith("Bearer ")) {
      throw new Error("Authentication required");
    }

    const token = authHeader.substring(7);
    // Verify token...

    return { authenticated: true };
  });

// Getting client information
const trackUserAction = createServerFn()
  .handler(async (action: string) => {
    const request = getRequest();
    const userAgent = getRequestHeader("user-agent");
    const clientIP = getRequestIP();
    const referer = getRequestHeader("referer");

    // Log the action with client information
    console.log({
      action,
      userAgent,
      clientIP,
      referer,
      timestamp: new Date().toISOString()
    });

    return { success: true };
  });

Response Utilities

Utilities for creating and manipulating HTTP responses.

/**
 * Create a JSON response with proper headers
 * @param data - Data to serialize as JSON
 * @param options - Response options
 * @returns JSON response object
 */
function json<T>(
  data: T,
  options?: { status?: number; headers?: HeadersInit }
): JsonResponse;

/**
 * Merge multiple header objects into one
 * @param headers - Header objects to merge
 * @returns Merged headers object
 */
function mergeHeaders(...headers: HeadersInit[]): Headers;

Usage Examples:

import { json, mergeHeaders } from "@tanstack/react-start";

// Create JSON responses
const getUsers = createServerFn()
  .handler(async () => {
    const users = await db.user.findMany();

    return json(users, {
      status: 200,
      headers: { "Cache-Control": "max-age=300" }
    });
  });

// Create responses with merged headers
const createUser = createServerFn()
  .handler(async (userData) => {
    const user = await db.user.create({ data: userData });

    const responseHeaders = mergeHeaders(
      { "Content-Type": "application/json" },
      { "X-User-ID": user.id },
      { "Cache-Control": "no-cache" }
    );

    return json(user, {
      status: 201,
      headers: responseHeaders
    });
  });

// Error responses
const deleteUser = createServerFn()
  .handler(async (userId: string) => {
    const user = await db.user.findUnique({ where: { id: userId } });

    if (!user) {
      return json(
        { error: "User not found" },
        { status: 404 }
      );
    }

    await db.user.delete({ where: { id: userId } });

    return json({ success: true });
  });

Advanced Usage Patterns

Request Body Processing

import { getRequest } from "@tanstack/react-start";

const processFormData = createServerFn()
  .handler(async () => {
    const request = getRequest();

    if (request.method !== "POST") {
      return json({ error: "Method not allowed" }, { status: 405 });
    }

    const contentType = getRequestHeader("content-type");

    if (contentType?.includes("application/json")) {
      const jsonData = await request.json();
      return json({ received: jsonData });
    } else if (contentType?.includes("multipart/form-data")) {
      const formData = await request.formData();
      const data = Object.fromEntries(formData);
      return json({ received: data });
    }

    return json({ error: "Unsupported content type" }, { status: 400 });
  });

CORS Handling

import { mergeHeaders, json } from "@tanstack/react-start";

const corsEnabledApi = createServerFn()
  .handler(async () => {
    const origin = getRequestHeader("origin");
    const allowedOrigins = ["https://example.com", "https://app.example.com"];

    const corsHeaders = allowedOrigins.includes(origin)
      ? {
          "Access-Control-Allow-Origin": origin,
          "Access-Control-Allow-Credentials": "true"
        }
      : {};

    const responseHeaders = mergeHeaders(
      { "Content-Type": "application/json" },
      corsHeaders
    );

    return json(
      { message: "API response" },
      { headers: responseHeaders }
    );
  });

Request Validation

const validateApiKey = createServerFn()
  .handler(async () => {
    const apiKey = getRequestHeader("x-api-key");
    const userAgent = getRequestHeader("user-agent");
    const clientIP = getRequestIP();

    if (!apiKey) {
      return json(
        { error: "API key required" },
        { status: 401 }
      );
    }

    // Rate limiting based on IP
    const requestCount = await redis.get(`requests:${clientIP}`);
    if (requestCount && parseInt(requestCount) > 100) {
      return json(
        { error: "Rate limit exceeded" },
        { status: 429 }
      );
    }

    // Validate API key
    const isValid = await validateAPIKey(apiKey);
    if (!isValid) {
      return json(
        { error: "Invalid API key" },
        { status: 403 }
      );
    }

    // Increment request count
    await redis.incr(`requests:${clientIP}`);
    await redis.expire(`requests:${clientIP}`, 3600);

    return json({ success: true });
  });

Types

// JSON response type
interface JsonResponse {
  json(): any;
  status: number;
  headers: Headers;
  ok: boolean;
  statusText: string;
}

// Request IP options
interface RequestIPOptions {
  ipHeader?: string;
}

Install with Tessl CLI

npx tessl i tessl/npm-tanstack--react-start

docs

index.md

isomorphic-functions.md

middleware.md

request-response.md

rpc-system.md

server-functions.md

server-utilities.md

ssr-components.md

vite-plugin.md

tile.json