⚔️ Code Conqueror

🖇️ Get the Current URL in Next.js

Nov 14, 2019

There are a number of cases that need to be handed properly when getting the current URL in Next.js. Those being, server vs client and local vs prod. It's important to be able to get the current URL, especially if you are using API routes and need to get that api data into your page through getInitialProps.

Typically

fetch
implementations (especially the recommended
isomorphic-unfetch
) require that the URL path be absolute, thus the requirement that you have someway to determine the host and protocol in different situations.

How to get the current URL in Next.js

We recommend using the great package

next-absolute-url
to get the current URL. It's a super straightforward function that you could also just copy/paste if you don't want dependency bloat:

function absoluteUrl(req, setLocalhost) {
var protocol = "https:";
var host = req
? req.headers["x-forwarded-host"] || req.headers["host"]
: window.location.host;
if (host.indexOf("localhost") > -1) {
if (setLocalhost) host = setLocalhost;
protocol = "http:";
}
return {
protocol: protocol,
host: host,
origin: protocol + "//" + host,
};
}

With this function you can easily get the right path in all of the four cases that we described above. An example usage to fetch a user list in the api route

api/users
would be:

import fetch from "isomoprhic-unfetch";
import absoluteUrl from "next-absolute-url";
const Users = ({ users }) => <div>{JSON.stringify(users)}</div>;
Users.getInitialProps = async ({ req, res }) => {
const { origin } = absoluteUrl(req, "localhost:3000");
const resp = await fetch(`${origin}/api/users`);
const users = await resp.json();
return { users };
};
export default Users;

If you want to re-write as little code as possible, you might even consider writing a

fetchRelative
function like:

import fetch from 'isomoprhic-unfetch';
import absoluteUrl from 'next-absolute-url';
const fetchRelative = path => {
const {origin} = absoluteUrl(req, 'localhost:3000');
return fetch(`${origin}${path}`);
}
const Users = ({users}) => (
<div>
{JSON.stringify(users)}
</div>
)
Users.getInitialProps = async ({req, res}) => {
const resp = await fetchRelative(`/api/users`);
const users = await resp.json();
return {users}
}
export default Users

and keep it in your

lib/
directory.