Are you tired of using generic profile pictures for your website or application? In this post, we'll show you how to use NextJS to generate unique, random SVG avatar images on the fly. With just a few lines of code, you can add a personal touch to your user profiles and stand out from the crowd.
In this tutorial, we'll be using the NextJS to build custom SVG avatar images. We'll be utilizing the @vercel/og
library, which allows us to easily create unique and dynamic images using the power of code.
Using this library, we can easily create customized avatars with different shapes, colors, and styles based on our needs. With NextJS, we'll be able to easily serve these dynamic images to our users, making the process of creating custom avatars both efficient and fun. So if you're ready to add some personality to your user profiles, let's get started!
We will be using NextJS version 12 or above. We'll also be working with React, so some understanding of how they work and how they can be used to create UI elements will be helpful. Additionally, we'll be working with SVG images, so having some understanding of the basics of how SVGs are created and how they differ from other image formats will be beneficial. If you are not familiar with any of these technologies, don't worry! There are plenty of resources available online that can help you get up to speed.
In order to start building custom SVG avatars with NextJS and the @vercel/og
library, we first need to set up a NextJS project. If you already have a NextJS project running, you can skip this step and proceed to install the @vercel/og
library.
Here's how you can create a new NextJS project:
npx create-next-app@latest my-avatars-app --typescript
I am going to be using typescript, but you can do it without typescript if you prefer.
cd my-avatars-app
npm run dev
http://localhost:3000
and you should see the default NextJS "Welcome to Next.js" page.Now you have the basic NextJS setup ready and you can start building your custom SVG avatar images using NextJS and @vercel/og
library.
@vercel/og
Library and Setting Up the API EndpointNow that you have a NextJS project set up, you can install the @vercel/og
library and set up an API endpoint that will be used to serve the dynamically generated SVG avatars. Here's what you need to do:
@vercel/og
library by running the following command in your project's directorynpm i @vercel/og
pages
folder, create a new file called api/avatars.tsx
(or .jsx
if you are not using TypeScript). Observe that we are using JSX
because we are going to be doing some React rendering on the API endpoint.avatars.tsx
endpoint import the ImageResponse
class from the @vercel/og
library and that's it, you are now able to build custom avatars for your users
import { ImageResponse } from '@vercel/og';
import type { NextApiRequest, NextApiResponse } from 'next';
export const config = {
runtime: 'edge',
};
export default function handler(req: NextRequest) {
return new ImageResponse(
(
<svg width="100" height="100" viewBox="0 0 100 100">
<circle cx="30" cy="30" r="4" fill="black" />
<circle cx="70" cy="30" r="4" fill="black" />
<path d="M 30 50 Q 50 60 70 50" stroke="black" stroke-width="5" fill="none" />
</svg>
),
{
width: 100,
height: 100,
},
);
}
Ok, we got it, a pretty bad avatar but it is a starting point. See the image below:
In this case for simplicity we are going to use some random numbers to generate the avatars. But it can be based on the user email and stored preferences, completely random, based on authentication tokens, etc.
For this example we will just generate random avatars, we will need a function to generate random numbers and one for selecting a random color:
function random(min: number, max: number, seed: number) {
return Math.floor(min + (max - min) * seed);
}
const colors = [
'#ffc857',
'#e9724c',
'#c5283d',
'#481d24',
'#255f85',
'#edffec',
'#61e786',
'#5a5766',
'#48435c',
'#9792e3',
] as const;
function randomColor(seed: number) {
return colors[random(0, colors.length, seed)];
}
Lastly we can draw a random avatar for the user by tuning the SVG:
export default function handler(req: NextRequest) {
return new ImageResponse(
(
<svg width="100" height="100" viewBox="0 0 100 100">
<rect width="100%" height="100%" fill={randomColor(Math.random())} />
<circle
cx={random(20, 40, Math.random())}
cy={random(20, 40, Math.random() / 2)}
r={random(1, 9, Math.random())}
fill="black"
/>
<circle
cx={random(60, 80, Math.random())}
cy={random(20, 40, Math.random())}
r={random(1, 9, Math.random())}
fill="black"
/>
<path
d={`M ${random(20, 40, Math.random())} ${random(40, 60, Math.random())} Q ${random(
30,
50,
Math.random(),
)} ${random(50, 70, Math.random())} ${random(60, 80, Math.random())} ${random(40, 60, Math.random())}`}
stroke="black"
stroke-width={random(1, 9, Math.random())}
fill="none"
/>
</svg>
),
{
width: 100,
height: 100,
},
);
}
Here you can see some results, which are actually hitting the API, you can try it at /api/examples/avatars. If you hit the API multiple times it will cache and return the same avatar. If you want to generate a different avatar you can include a param ?p=<some-random-number>
.
This now looks better, but the Avatars are not persistent, they are cached on Vercel's edge locations, but for storing the parameters (random numbers) that we used for each avatar we would need some kind of storage, there are several options but we will not cover that topic today.
My main goal with the blog post was to learn and explore the @vercel/og
library and provide a basic idea of how it can be used for generating something like an Avatar. After playing around with the library for some hours I think it is a great tool and it is really powerful. If you have some kind of need to generate images dynamically I would really recommend that you give it a try.