Walkthrough: Starting a Makerkit project with Firebase and Next.js

This walkthrough is a summary of the documentation to quickly bootstrapping a SaaS project with Makerkit

·9 min read
Cover Image for Walkthrough: Starting a Makerkit project with Firebase and Next.js

This blog is a summary of the documentation to get started with the Next.js + Firebase boilerplate project quickly and smoothly.

System Requirements

To get started, you must install Node.js and Git on your system.

If these are already installed, we only recommend you install the Firebase Tools globally using the following command:

npm i -g firebase-tools

Cloning the repository

If you have access to the MakerKit private team, you can fetch the repository from Git using the following command and by replacing your-saas-app with the name you prefer:

git clone --depth=1 https://github.com/makerkit/next-firebase-saas-kit your-saas-app

If you have purchased from Gumroad, you may not yet have access to the team. In that case, simply install the packages and wait for us to add you to the private team on GitHub.

Now, let's get in the folder and install the Node packages using npm:

cd your-saas-app
npm i

To test that everything works, let's run the following commands in two separate terminals (or, better, using your IDE).

Running the Next.js server in development mode

npm run dev

Running the Firebase Emulators

npm run firebase:emulators:start

If everything goes well, you should be able to open the application at http://localhost:3000.

Running the Stripe CLI

Additionally, if you want to run Stripe locally (e.g. sending webhooks to your local server), you will also need to run the following command:

npm run stripe:listen

The above command runs the Stripe CLI and will route webhooks coming from Stripe to your local endpoint. For example, in the Makerkit starter, this endpoint is /api/stripe/webhook.

When running the command, it will print a webhook key used to sign the messages from Stripe. You will need to add this key to your local environment variables file as below:

STRIPE_WEBHOOK_SECRET=<KEY>

The webhook printed should not change, so you may only need to do this the first time.

Yep, no more configuration needed!

As you may have noticed, we required no configuration changes. This is for two reasons:

  1. We're using a "demo" project. Any project that starts with demo- will never be treated as an actual project by the Firebase tooling
  2. Some of the environment variables (API key and APP ID) are pasted from another Makerkit's project, but we invite you to change these as soon as you create a project. This is done so you can get started as quick as possible.

Screens and Functionalities

Let's take a look at each screen of the boilerplate and its functionalities.

Generally, we split the application into two parts:

  1. The public marketing website, containing:
  • the landing page, FAQ, pricing and contact pages
  • the blog
  • the documentation
  1. The application, only accessible via authentication:
  • the dashboard (or home page of the "app")
  • the settings pages
  • any other protected page you will create

Additionally, we have the authentication pages, that sit a bit in the middle between the two layers, such as:

  • the sign-in page
  • the sign-up page
  • the reset password page
  • the accept invite page

Landing Page

At the time of writing, the landing page will be fairly simple and empty, and it's by design: we bet you will want to make many changes.

As you may have noticed, you can toggle the dark theme using the moon icon in the header.

Blog and Documentation

The boilerplate's blog and documentation pages are both accessible from the marketing site's header.

Loading video...

Adding a Blog Post

The MakerKit's blog posts use MDX. To write a blog post:

  1. create a specific "collection" or "category" by adding a json file at _collections/filename.json. Use the existing collection as an example.
  2. add an MDX file at _posts, and fill the matter to make the post valid. The boilerplate has an example, so you can simply copy the same metadata to quickly get started.

Remember to:

  1. Restart the Next.js server command when adding a new file
  2. Refresh the page to pick up changes as hot reload does not work

Adding a new documentation page

The documentation works very similarly to the blog. In the documentation we have topics and pages:

_docs
  [topic]
    [page]

Every topic folder needs to have a meta.json file, with the following content:

{
  "title": "Topic Title",
  "position": 0,
  "description": "Description"
}

While title and description are self-explanatory, you should be aware that the position property is needed to place the topic at the correct position within the documentation.

Instead, pages need to have the following matter metadata:

---
title: Page Title
label: Page Label within the sidebar tree
position: 0
description: Description
---

For each page, and similarly to the topics, you have to specify the page's position.

Loading video...

Authentication

At the time of writing, the Makerkit's SaaS boilerplate supports authentication via email/password or third-party providers supported by Firebase Authentication.

Signing Up

By navigating to /auth/sign-up, users will be able to sign up to the application.

Onboarding

The first time the user signs up, they will be redirected to the onboarding page: here is where you can ask for useful information and set up the user's organization and account.

By default, Makerkit's only asks for the name of the organization the user is creating. In fact, a user needs to belong to an organization.

Once submitted the form, the user will be brought to the home page of the application, which in the Makerkit's starter is /dashboard, but that you can easily configure from the application's configuration.

Signing In

By navigating to /auth/sign-in, users will be able to sign in to the application.

Application Home Page

The home page of the application, by default, is at /dashboard. This is easily configurable in the application's configuration.

Creating and Switching Organizations

Organizations (or groups of users) are central to any SaaS application. The starter allows users to belong to multiple projects, create more projects and switch between projects on all the internal pages.

Switching and creating organizations happens through a dropdown, which can be found either in the sidebar (if using the sidebar layout) on in the application header (if using the top-navigation header).

Loading video...

Application Settings

Much of the logic and complexity of the boilerplate is in its settings, as this is the part that overlaps the most between SaaS applications.

Update Profile

The Update Profile Page allows your users to update their profiles. For example, they'll be able to update their name, profile photo, and if they signed up by email, also their email and password.

Loading video...

Update Organization

The Update Organization Page allows your users to update their organizations, depending on their role. For example, by default, they'll be able to update the organization's name and logo.

Loading video...

Organization Members

The organization members page lists the current members, and the invited members, and allows users to perform certain actions such as deleting an invite, removing users, and changing a user's role.

From now on, we will update the layout of the application by switching from Sidebar to TopHeader.

Inviting Members

When clicking on "Invite Members", the user is redirected to the form below, from which users can add many members at once:

When the user is invited, it gets added to the list:

Loading video...

Testing Emails with Ethereal

During development, emails are sent to Ethereal accounts.

You can create an account and set the environment variables to use always the same account. Alternatively, a testing account will be created on the fly, and you will need to log in using the credentials logged in the console.

To set a fixed Ethereal account:

  1. Create an account, get the credentials
  2. Add the credentials to the .env.development file using the variables ETHEREAL_EMAIL and ETHEREAL_PASSWORD.

Alternatively, you will find your testing account details in the console:

Accepting an Invite

In the image below, we logged in Ethereal to retrieve the email sent to the user. From here we can copy the link and navigate to it.

As you can imagine, we can encounter two situations:

  1. users are already signed-in when clicking on the link
  2. users do not have an account and therefore are not signed-in

Users accepting invitations who are logged out

This is the more straightforward scenario: the user doesn't have an account and is signed out, therefore can choose their credentials and sign-up.

Users accepting invitations who are logged in

This is a more complex scenario, because the user may inadvertently accept the invite with the currently signed-in account. Instead, they may want to use a different account based on the invite.

In this case, we explicitly clarify which account the user is accepting the invite with, and offer the possibility to sign out if they wanted to use another one:

Stripe Subscriptions and Payments

Makerkit allows setting up Stripe with ease to collect payments from your SaaS users. To do so, users can visit the Subscriptions page from the Settings.

Setting up a plan selector

Assuming you have already subscribed to Stripe, and have created prices and products in Stripe, you can create an automatic plan selector by adding your prices to the Makerkit configuration. At the time of writing, this is fairly basic, but it gives you an idea of how to expand it to suit your needs.

First, we add the plans to the ./configuration.ts file. In the example below, we add two plans: Basic and Pro.

plans: [
  {
    name: 'Basic',
    description: 'Unlimited applications and 2-hour onboarding session',
    price: '$249/year',
    stripePriceId: '',
  },
  {
    name: 'Pro',
    description: 'Unlimited applications and a full-day onboarding session',
    price: '$999/year',
    stripePriceId: '',
  },
],

Of course, you'll need to make sure you update the correct stripePriceId that you can find in your Stripe console.

When choosing a plan, the checkout button will take the user to the Stripe Checkout Portal, which is Stripe's hosted portal where users can safely pay for your SaaS' services.

Loading video...

Once the user subscribed to a plan, they will also be able to manage their billing and invoices using the Stripe Billing Portal. Additionally, they can unsubscribe from the plan they chose:

Loading video...

Personalization

There are a few things you may want to update when starting your project:

  1. Updating the package.json references to Makerkit
  2. Updating the logo LogoImage.tsx and the favicon with your own
  3. Updating the Tailwind theme colors

The first two points are very straightforward, so we'll discuss the third one.

Updating the Tailwind colors

By updating the Tailwind theme, you will be able to give your project its own look & feel. To do so, we will open the Tailwind configuration at tailwind.config.js and update the colors.

The Starter extends the colors with two new types: primary and black (in my opinion, a nicer shade of blacks).

What you will want to change is primary. To do so, pick the main color of your theme, and use this Material colors palette generator to automatically generate a palette of colors.

Once chosen the main color, you can copy the colors by using the "View Code" button and then choosing "Material UI Next (React)", which returns a nice JSON configuration ready to be pasted.

Finally, simply replace the Makerkit's colors with the ones from the palette you generated.

Conclusion

This walkthrough helps you get started with the Next.js + Firebase boilerplate and introduces the main features that the project provides.

If you have any questions, do not hesitate to contact us!


Stay informed with our latest resources for building a SaaS

Subscribe to our newsletter to receive updatesor

Read more about

Cover Image for How to sell code with Lemon Squeezy and Github

How to sell code with Lemon Squeezy and Github

·7 min read
Sell and monetize your code by giving private access to your Github repositories using Lemon Squeezy
Cover Image for Writing clean React

Writing clean React

·9 min read
Learn how to write clean React code using Typescript with this guide.
Cover Image for How to use MeiliSearch with React

How to use MeiliSearch with React

·12 min read
Learn how to use MeiliSearch in your React application with this guide. We will use Meiliseach to add a search engine for our blog posts
Cover Image for Setting environment variables in Remix

Setting environment variables in Remix

·3 min read
Learn how to set environment variables in Remix and how to ensure that they are available in the client-side code.
Cover Image for Programmatic Authentication with Supabase and Cypress

Programmatic Authentication with Supabase and Cypress

·3 min read
Testing code that requires users to be signed in can be tricky. In this post, we show you how to sign in programmatically with Supabase Authentication to improve the speed of your Cypress tests and increase their reliability.
Cover Image for Reset the Supabase Database in Cypress

Reset the Supabase Database in Cypress

·4 min read
Resetting your database during E2E tests is important to prevent flakiness. In this tutorial, we'll show you how to reset the Supabase database in Cypress E2E tests.