Creating a resume with React or other frontend technologies is often viewed as a simple task for one to try out his frontend skills. But while this project is simple, it is also very easy to mess up and over-engineer.
In this tutorial, you will learn how to create a simple resume with Next.js with the resume data hosted on BCMS, a headless CMS. Why this approach you may ask?
Easier Content Updates: With your resume content hosted separately from your app, you can modify your resume without touching your codebase.
Real-Time Updates: You can make changes on your CMS and they’re instantly reflected on the Next.js website.
Customization and Integration: Headless CMSs often have APIs allowing deep customization. If you need to integrate with other services (like job application APIs, LinkedIn, or GitHub), a CMS can facilitate these integrations more seamlessly than hard-coded data.
These features do not come standard with any CMS, so using a headless CMS with these and other features is essential. . That is why for this tutorial we’re gonna be using BCMS. A modern, minimalistic CMS designed for Developers and content editors.
By the end of this tutorial, you will be able to harness the power of Next.js and the super features that BCMS provides to create a fully functional resume website.
copy the terminal command and paste it on your terminal to create a simple BCMS Next project using one of the starters available. For this tutorial, I will be using the simple blog template.
npx @thebcms/cli create next starter simple-blog
This Command will create a next.js project, clone the simple-blog starter inside of it, and then connect to a BCMS instance(more on this later). This is where it requires you to log in, so simply log in when it prompts you to log in using your browser or create a new account if you don’t have a BCMS account yet.
After logging in, the command will prompt you for the name of the project and then successfully create it, as shown in the image below.
Now your Next.js project is ready to go and is linked to a BCMS backend, which is where these blog posts are coming from. We don't need these blog posts, though, because our needs are different. So, Let's clean up the page.
Page Cleanup
Navigate to the src folder, followed by app, in your newly created Next.js project. There's page.tsx, which is the index page, and that's the only page we'll use for this tutorial because it's a one-page resume with no links to other pages.
First, I'll remove the BlogCard and Tag templates that I won't be using, as well as the BlogEntry types that were automatically generated for us when we used the bcms CLI command.
//Delete
import { BlogEntry, BlogEntryMetaItem } from '../../bcms/types/ts';
import BlogCard from '@/components/blog/Card';
import Tag from '@/components/Tag';
After that you can change the page title to any title of your choice.
Moving on to the HomePage function, Remove all functions and clean up the return statement leaving just a div there with a simple “My Resume”.
The code for the page.tsx should look something like this at this point:
import React from 'react';
import { bcms } from './bcms-client';
import { Metadata } from 'next';
const pageTitle = 'Resume - My Simple Resume';
export const metadata: Metadata = {
title: pageTitle,
openGraph: {
title: pageTitle,
},
twitter: {
title: pageTitle,
},
};
const HomePage: React.FC = async () => {
return <div>My Resume</div>;
};
export default HomePage;
And on the browser, this is what will be displayed.
Great, with the project cleaned up, it is time to set up the UI for the resume.
Designing Page UI
Now, I will set up the page for the resume and for now, it will hold dummy hardcoded data.
This requires creating the page's HTML structure and then styling it with tailwindcss. I will not go into detail about the CSS or tailwindCSS used to style the page because this is not a CSS tutorial; instead, simply copy the page and replace your existing page.tsx code with it.
import React from 'react';
import { bcms } from './bcms-client';
import { Metadata } from 'next';
import Image from 'next/image';
const pageTitle = 'Resume - My Simple Resume';
export const metadata: Metadata = {
title: pageTitle,
openGraph: {
title: pageTitle,
},
twitter: {
title: pageTitle,
},
};
const HomePage: React.FC = async () => {
return (
<div className="w-8/12 mx-auto mt-6 bg-white px-20 py-12">
<header className="flex flex-row justify-between mb-4">
<section className="name">
<h1 className="font-bold text-3xl">Your Name</h1>
<h3 className="text-2xl">Senior Product Designer</h3>
</section>
<section className="profile-photo mr-24">
<Image
src="/images/avatar.svg"
height={90}
width={90}
alt="resume profile picture"
/>
</section>
</header>
<main className="details flex justify-between gap-10">
<section className="basis-[60%]">
<h4 className="uppercase text-[#73808D] text-sm tracking-widest mb-1">
Experience
</h4>
<div className="mb-6">
<h1 className="font-bold mb-1">
Senior UI/UX Product Designer
</h1>
<h3 className="mb-1">Enterprise Name</h3>
<h4 className="text-[#73808D] text-sm">
Aug 2018 - Present - 1 year, Paris
</h4>
<p>
Directly collaborated with CEO and Product team to
prototype, design and deliver the UI and UX
experience with a lean design process: research,
design, test, and iterate.
</p>
</div>
<div className="mb-6">
<h1 className="font-bold mb-1">
UI/UX Product Designer
</h1>
<h3>Enterprise Name</h3>
<h4 className="text-[#73808D] text-sm">
Aug 2013 - Aug 2018 - 5 years, Paris
</h4>
<p>
Lead the UI design with the accountability of the
design system, collaborated with product and
development teams on core projects to improve
product interfaces and experiences.
</p>
</div>
<div className="mb-6">
<h1 className="font-bold mb-1">UI Designer</h1>
<h3>Enterprise Name</h3>
<h4 className="text-[#73808D] text-sm">
Aug 2012 - July 2013, Paris
</h4>
<p>
Designed mobile UI applications for Orange R&D
departement, BNP Paribas, La Poste, Le Cned...
</p>
</div>
<div className="mb-6">
<h1 className="font-bold mb-1">Graphic Designer</h1>
<h3>Enterprise Name</h3>
<h4 className="text-[#73808D] text-sm">
Sept 2010 - jul 2012 - 2 years, Paris
</h4>
<p>
Designed print and web applications for Pau Brasil,
Renault, Le théatre du Mantois, La mairie de Mantes
la Ville...
</p>
</div>
<h4 className="uppercase text-[#73808D] text-sm tracking-widest mb-1">
Education
</h4>
<div className="mb-6">
<h1 className="font-bold mb-1">
Bachelor European in Graphic Design
</h1>
<h3>School Name</h3>
<h4 className="text-[#73808D] text-sm">
2009 - 2010, Bagnolet
</h4>
</div>
<div className="mb-6">
<h1 className="font-bold mb-1">
BTS Communication Visuelle option Multimédia
</h1>
<h3>School Name</h3>
<h4 className="text-[#73808D] text-sm">
2007 - 2009, Bagnolet
</h4>
</div>
</section>
<section className="text-[#73808D] basis-[30%]">
<div className="contact mb-4">
<p>[email protected]</p>
<p>+33 6 33 33 33 33</p>
<p>Vernouillet</p>
</div>
<div className="mb-4">
<h3 className="font-bold">Industry Knowledge</h3>
<p>Industry Knowledge</p>
<p>Product Design</p>
<p>User Interface</p>
<p>User Experience</p>
<p>Interaction Design</p>
<p></p>
</div>
<div className="mb-4">
<h3 className="font-bold">Tools & Technologies</h3>
<p>
Figma, Sketch, Protopie, Framer, Invision, Abstract,
Zeplin, Google Analytics, Amplitude, Fullstory...
</p>
</div>
<div className="mb-4">
<h3 className="font-bold">Other Skills</h3>
<p>HTML, CSS, jQuery</p>
</div>
<div className="mb-4">
<h3 className="font-bold">Languages</h3>
<p>French (native)</p>
<p>English (professionnal)</p>
</div>
<div className="mb-4">
<h3 className="font-bold">Social</h3>
<p>yoursite.com</p>
<p>linkedin.com/in/yourname</p>
<p>dribbble.com/yourname</p>
</div>
</section>
</main>
</div>
);
};
export default HomePage;
From the code above, you can see that you need a photo, for now it will be hosted on our Next.js Project but it will be changed later, so simply go to the public folder, create a new folder named images and save a portrait of your choice to use as a sample profile photo.
Moving on, go to the layout.tsx file under the app folder and change the background color so we get a more beautiful feel and focus on the resume section.
<body className={`${inter.className} overflow-x-hidden bg-[#E5E5E5]`}>
After that, your page should have come to life
to login to your BCMS account. On the left side of your dashboard, you see a dropdown containing a list of your BCMS instances(also called projects).
BCMS instance is just like a box or repository containing your application data, so this is the backend for that particular application. You can create different instances for different applications.
-** This is your content structure, your building block. Here is where you spell out what fields you need for the section you’re creating a template for.
- Groups in BCMS are reusable building blocks made of multiple , or other group.
Let’s see this in action.
Modelling Data in BCMS
On your templates tab, you’ll find a blog template which was automatically generated upon the creation of this project using the CLI command up above. Since you’ve gotten rid of all blog related files on your frontend app, it means the blog template is no longer useful to you. So, click on this template, and then click on edit template on the top right of the page, and then safely delete it.
So what is the data needed for this resume?
- Name - String - Required
- Title - Automatically created by BCMS
- Profile Picture - Media - Required
Now back to the Resume template, you can now successfully link to this group, and it should be an array since it will be holding multiple work experiences.
Contact information - This will be a group holding the contact information
Next up, go to the entries tab and then click on the resume to create an entry, there you can now write the actual resume data following the structure which you just defined in the template.
Simply edit the fields there and after doing that click on the status drop down on the right side of the page, change it to published and then update.
With that you’ve successfully written your data and you’re ready to have it on your next.js app.
But before that, we need to update our API key permissions. Navigate to settings and then the API key, click on edit and you should see permissions for the newly created Resume template. Toggle the ones you need on, for this tutorial that will be “can get”. Without this permission, you will not be able to get resume data on your Nextjs frontend.
You can also log more fields to see what you can get. For example, I’m gonna log the meta object as it is the object that holds our entry.
Deployment🚀
To deploy your Next.js app, you need to use a service called Vercel. It's a straightforward way to make your website live on the internet. Follow this tutorial to learn how to use Vercel.🚀
Next steps
To sum it up, creating a resume using NextJS headless CMS is simple and powerful. BCMS headless CMS helps you manage your resume’s content, while Next.js makes sure your website works well. The resume you've created is not just for show – it's a starting point for you to explore what BCMS can do. With BCMS, you can easily adapt your website to different needs and connect it with other tools.
You have created this one-page resume, but you can take it further by making it multiple. That means in the resume template you can make it a non-single-entry to create multiple resumes for different needs. Maybe a Java resume and then a UI design resume that you show to different recruiters.
BCMS makes this process really simple, by just toggling off single entry in the template, you will be able to create multiple resumes, and then on your nextjs app, you get those different resumes and display them on different urls just like a blog works.
Well with that I will say happy coding and let’s see what you’re able to achieve with Nextjs and BCMS.🙌
SOCIAL SHARE CARD GENERATOR