ReactHustle

How to Get Absolute URL in NextJS

Jasser Mark Arioste

Jasser Mark Arioste

How to Get Absolute URL in NextJS

If you're nextJS project is deployed in Vercel, the origin URL changes if it's a preview branch deployment. In this tutorial, you'll learn how to get the absolute URL in NextJS for both client and server.

There are many ways to get the absolute URL in NextJS and it depends on your situation. If you have access to the window object or request object (NextRequest, NextApiRequest, IncomingMessage), it will be much easier. 

With all of that out of the way, let's start!

Absolute URL in React Component #

Components can be rendered on both the client-side and server-side. If you need access to the absolute URL inside components, the best practice is to create some utility functions.

First, create a file utils/vercel-utils.tsx, and create some utility functions and variables:

// utils/vercel-utils.tsx
export const IS_SERVER = typeof window === "undefined";
export function getProtocol() {
  const isProd = process.env.VERCEL_ENV === "production";
  if (isProd) return "https://";
  return "http://";
}
export function getAbsoluteUrl() {
  //get absolute url in client/browser
  if (!IS_SERVER) {
    return location.origin;
  }
  //get absolute url in server.
  const protocol = getProtocol();
  if (process.env.VERCEL_URL) {
    return `${protocol}${process.env.VERCEL_URL}`;
  }
}
123456789101112131415161718

Explanation:
Line 2: Check if we are rendering from the server or client by checking if window is undefined.

Lines 3-7: getProtocol -  A utility function to get the HTTP protocol. We use https for production and http for development

Lines 8-18: getAbsoluteUrl - easily get the absolute URL for both client and server. For the client-side, it's pretty much self-explanatory. For server-side, we make use of process.env.VERCEL_URL, a system environment variable that Vercel provides on every deployment.

Once created, you'll be able to do this:

...
const ComponentA = () => {
  const absoluteUrl = getAbsoluteUrl();
  return (
    <div>
      <div>fromInsideComponent Absolute URL: {absoluteUrl}</div>
    </div>
  );
};
123456789

You can use this function anywhere in the application. The downside of this is the reliance on Vercel environment variables. You'll have to modify your code if you decide to transfer to another provider like digital ocean or AWS.

Absolute URL inside middleware.ts #

If you're inside middleware.ts, to get the absolute URL in NextJS you can get the URL by relying on NextRequest :

import { NextRequest } from "next/server";
export function middleware(req: NextRequest) {
  //simply create a new URL from req.url
  const absoluteUrl = new URL("/", req.url).toString();
  console.log("Middleware", absoluteUrl);
}
123456

Absolute URL inside /api paths #

If you're inside /api handlers, you can get the absolute URL by using NextApiRequest and the getProtocol utility function we created earlier:

// pages/api/hello.tsx
import type { NextApiRequest, NextApiResponse } from "next";
import { getProtocol } from "utils/vercel-utils";
export default function handler(req: NextApiRequest, res: NextApiResponse) {
  res.status(200).json({ url: `${getProtocol()}${req.headers.host}` });
}
123456

Absolute URL inside getServerSideProps: #

Inside getServerSideProps, we can use ctx.req.headers.host and the getProtocol function from before:

...
export const getServerSideProps: GetServerSideProps<Props> = async (ctx) => {
  console.log("host", ctx.req.headers.host);
  const absoluteUrl = `${getProtocol()}${ctx.req.headers.host}`;
  return {
    props: {
      absoluteUrl,
    },
  };
};
12345678910

You can also use ctx.req.headers.origin, but sometimes this changes if you're accessing the website from a proxy server so I think it's better to stick to host.

...
export const getServerSideProps: GetServerSideProps<Props> = async (ctx) => {
  const absoluteUrl = ctx.req.headers.origin;
  return {
    props: {
      absoluteUrl,
    },
  };
};
123456789

Absolute URL inside getStaticProps: #

Inside getStaticProps, there's no request object so we'll have to use the utility function getAbsoluteUrl from earlier:

import { GetStaticProps, NextPage } from "next";
import React from "react";
import { getAbsoluteUrl } from "utils/vercel-utils";
type Props = {
  absoluteUrl: string;
};
const StaticPage: NextPage<Props> = ({ absoluteUrl }) => {
  const fromInsideComponent = getAbsoluteUrl();
  return (
    <div>
      <div>getStaticProps Absolute URL: {absoluteUrl}</div>
      <div>fromInsideComponent Absolute URL: {fromInsideComponent}</div>
    </div>
  );
};
export default StaticPage;
export const getStaticProps: GetStaticProps<Props> = async (ctx) => {
  return {
    props: {
      absoluteUrl: getAbsoluteUrl() ?? "",
    },
  };
};
1234567891011121314151617181920212223

That's it!

Code and Demo #

If you need to look at the code, I created a GitHub repo which you can use by using the command 

npx create-next-app -e https://github.com/jmarioste/next-absolute-url-tutorial next-absolute-url
1

For the demo, you can check them at these links. 

Conclusion #

We learned how to get the absolute URL in different parts of the application. There are many ways, but remember to use what's best suited for the job.

If you like this tutorial, please leave a like or share this article. For future tutorials like this, please subscribe to our newsletter or follow me on Twitter.

Credits: Image by Armin Forster from Pixabay

Share this post!

Related Posts