frameworkEdit this page

HTTP context

With @lazarv/react-server you have access to everything related to the context of server-side rendering. This guide provides information for you how to access the HTTP context.

The following hooks / functions are available for you to access and manipulate the HTTP context.

All of these functions are available also in middlewares and route handlers with the file-system based router as these are framework specific and not related to React.

With useHttpContext() you can get access to the full HTTP context.

import { useHttpContext } from "@lazarv/react-server";

export default function MyComponent() {
  const context = useHttpContext();

  return (
    <div>
      <p>Method: {context.request.method}</p>
      <p>URL: {context.request.url.toString()}</p>
      <p>Request Headers: {JSON.stringify(context.request.headers)}</p>
      <p>Request Cookies: {JSON.stringify(context.request.cookie)}</p>
    </div>
  );
};

With useRequest() you can get access to the full HTTP request.

import { useRequest } from "@lazarv/react-server";

export default function MyComponent() {
  const request = useRequest();

  return (
    <div>
      <p>Method: {request.method}</p>
      <p>URL: {request.url.toString()}</p>
      <p>Headers: {JSON.stringify(request.headers)}</p>
      <p>Cookies: {JSON.stringify(request.cookie)}</p>
    </div>
  );
};

With useResponse() you can get access to the full HTTP response. This is only available after the response has been sent to the client, in a React component which was suspended and streamed to the client later than the response was sent.

import { useResponse } from "@lazarv/react-server";

export default function MyComponent() {
  const response = useResponse();

  return (
    <div>
      <p>Headers: {JSON.stringify(response.headers)}</p>
      <p>Cookies: {JSON.stringify(response.cookie)}</p>
    </div>
  );
};

With useUrl() you can get access to the URL of the current request.

import { useUrl } from "@lazarv/react-server";

export default function MyComponent() {
  const url = useUrl();

  return <p>URL: {url.href}</p>;
};

With usePathname() you can get access to the pathname of the current request.

import { usePathname } from "@lazarv/react-server";

export default function MyComponent() {
  const pathname = usePathname();

  return <p>Pathname: {pathname}</p>;
};

With useSearchParams() you can get access to the search params of the current request. This is an object with key-value pairs of the search params. In case of multiple values for the same key, the value will be an array.

import { useSearchParams } from "@lazarv/react-server";

export default function MyComponent() {
  const searchParams = useSearchParams();

  return (
    <p>Search params: {JSON.stringify(searchParams)}</p>
  );
};

With headers() you can get access to the headers of the current request.

import { headers } from "@lazarv/react-server";

export default function MyComponent() {
  const requestHeaders = headers();

  return <p>Headers: {JSON.stringify(requestHeaders)}</p>;
};

You can also modify the headers of the current response by passing an object of key-value pairs:

import { headers } from "@lazarv/react-server";

export default function MyComponent() {
  headers({
    "X-My-Header": "My value",
  });

  return <p>Headers: {JSON.stringify(headers())}</p>;
};

Or by passing a Headers object:

import { headers } from "@lazarv/react-server";

export default function MyComponent() {
  headers(new Headers({
    "X-My-Header": "My value",
  }));

  return <p>Headers: {JSON.stringify(headers())}</p>;
};

Or by passing an array of key-value pairs:

import { headers } from "@lazarv/react-server";

export default function MyComponent() {
  headers([
    ["X-My-Header", "My value"],
  ]);

  return <p>Headers: {JSON.stringify(headers())}</p>;
};

Modifying the headers with the headers() function will override the headers of the current response. If you want to mutate the response headers directly, you can use three addition helper functions to set, append or delete headers. These functions are setHeader(), appendHeader() and deleteHeader().

import { setHeader, appendHeader, deleteHeader } from "@lazarv/react-server";

export default function MyComponent() {
  setHeader("X-My-Header", "My first value");
  appendHeader("X-My-Header", "My second value");
  deleteHeader("X-My-Header");

  return <p>Check the response headers!</p>;
}

Note: Keep in mind that HTTP headers are case-insensitive!

With cookie() you can get access to the cookies of the current request.

import { cookie } from "@lazarv/react-server";

export default function MyComponent() {
  const requestCookies = cookie();

  return <p>Cookies: {JSON.stringify(requestCookies)}</p>;
};

You can also set or delete cookies in the context of the current response.

import { setCookie, deleteCookie } from "@lazarv/react-server";

export default function MyComponent() {
  setCookie("my-cookie", "my-value");
  deleteCookie("other-cookie");

  return <p>Cookies: {JSON.stringify(cookie())}</p>;
};

With status() you can set the status code and text of the current response.

import { status } from "@lazarv/react-server";

export default function MyComponent() {
  status(404, "Not found");

  return <p>Not Found</p>;
};

With useFormData() you can get access to the form data of the current request.

import { useFormData } from "@lazarv/react-server";

export default function MyComponent() {
  const formData = useFormData();

  return (
    <p>Form data: {JSON.stringify(Object.fromEntries(formData.entries()))}</p>
  );
};

With redirect() you can redirect the current request to another URL.

Warning: the redirect() function will throw an error which will be caught by the framework and will result in a redirect. When you want to use redirect() in a try/catch block, make sure you rethrow the error if it's a redirect error.

import { redirect } from "@lazarv/react-server";

export default function MyComponent() {
  redirect("https://example.com");
};

With rewrite() you can rewrite the current request to another URL. This is useful to modify the URL pathname of the current request in a middleware function.

import { rewrite, useUrl } from "@lazarv/react-server";

export function init$() {
  return async () => {
    const { pathname } = useUrl();

    if (pathname === "/old-pathname") {
      rewrite("/new-pathname");
    }
  };
}

export default function MyComponent() {
  const { pathname } = useUrl();

  return <p>Current pathname: {pathname}</p>;
}

With useOutlet() you can get access to the outlet of the current request. This is useful to get the name of the outlet where the current request is rendered.

import { useOutlet } from "@lazarv/react-server";

export default function MyComponent() {
  const outlet = useOutlet();

  return <p>Outlet: {outlet}</p>;
}

With useRender() you can get access to the render lock of the current request. This is useful if you want to lock rendering of a React Server Component while the async function is running or until the lock is released, as React Server Components are rendered using streaming by default. This is especially useful for handling HTTP headers and cookies in an async React Server Component. Without locking the rendering, the headers and cookies will be sent to the client before the async function is finished. When a lock is detected in the rendering process, the rendering will wait for the lock to be released before beginning to send the headers and cookies to the client and starting the streaming of the React Server Component.

import { headers, useRender } from "@lazarv/react-server";

export default function MyComponent() {
  const { lock } = useRender();

  await lock(async () => {
    // Do something async
    await new Promise((resolve) => setTimeout(resolve, 1000));
    headers({
      "x-lock": "works",
    });
  });

  return <p>Render lock</p>;
}

You can also use the lock() function to get an unlock() function to release the lock later.

import { headers, useRender } from "@lazarv/react-server";

export default function MyComponent() {
  const { lock } = useRender();

  const unlock = lock();
  // Do something async
  await new Promise((resolve) => setTimeout(resolve, 1000));
  headers({
    "x-lock": "works",
  });
  unlock();

  return <p>Render lock</p>;
}