avatarR-Dev

Summarize

Building a NextJS Firebase App with Tailwind CSS: A Comprehensive Guide

In this article, we will go beyond just Firebase integration and cover the step-by-step process of setting up a React app with Tailwind CSS, Firebase, and react-hook-form. This guide assumes you have a basic understanding of React and Node.js.

1. Setting Up Your React Project

Assuming you already have Node.js and npm installed, let’s create a new React app using Create React App. Open your terminal and run:

npx create-next-app@latest my-firebase-app
cd my-firebase-app

2. Installing Tailwind CSS

Next, install Tailwind CSS and its dependencies:

npm install -D tailwindcss postcss autoprefixer

Generate the configuration files for Tailwind CSS:

npx tailwindcss init -p

This will create tailwind.config.js and postcss.config.js in your project's root.

3. Configuring Tailwind CSS in Next.js

Update postcss.config.js to include the tailwindcss and autoprefixer plugins:

// postcss.config.js
module.exports = {
  plugins: {
    tailwindcss: {},
    autoprefixer: {},
  },
};

tailwind.config.js file:

/** @type {import('tailwindcss').Config} */
module.exports = {
  content: [
    './src/pages/**/*.{js,ts,jsx,tsx,mdx}',
    './src/components/**/*.{js,ts,jsx,tsx,mdx}',
    './src/app/**/*.{js,ts,jsx,tsx,mdx}',
  ],
  theme: {
    extend: {
      backgroundImage: {
        'gradient-radial': 'radial-gradient(var(--tw-gradient-stops))',
        'gradient-conic':
          'conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))',
      },
    },
  },
  plugins: [],
}

Create a CSS file for your styles, typically src/styles/tailwind.css, and import Tailwind CSS:

/* src/globals.css */
@import 'tailwindcss/base';
@import 'tailwindcss/components';
@import 'tailwindcss/utilities';

Import this CSS file in your src/layout.js or src/layout.jsx:

// src/layout.js or layout.jsx
import { Inter } from 'next/font/google'
import './globals.css'

const inter = Inter({ subsets: ['latin'] })

export const metadata = {
  title: 'Create Next App',
  description: 'Generated by create next app',
}

export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <body className={inter.className}>{children}</body>
    </html>
  )
}

4. Installing react-hook-form

Install react-hook-form for form handling:

npm install react-hook-form uuid

Setting Up Firebase Configuration

The first step is to configure Firebase for your React project. The code in /lib/firebase-config.js handles this by importing the necessary Firebase modules and initializing the app with the provided configuration. Make sure to replace the placeholder values in firebaseConfig with your Firebase project's actual configuration.

// /lib/firebase-config.js
import { initializeApp } from "firebase/app";
import { getApps, getApp } from "firebase/app";
import { getAuth } from "firebase/auth";
import { getStorage } from "firebase/storage";
import { getFirestore } from "firebase/firestore";

// TODO: Add SDKs for Firebase products that you want to use
// https://firebase.google.com/docs/web/setup#available-libraries

// Your web app's Firebase configuration
const firebaseConfig = {
  apiKey: "",
  authDomain: "",
  projectId: "",
  storageBucket: "",
  messagingSenderId: "",
  appId: "",
};

// Initialize Firebase
const app = getApps().length > 0 ? getApp() : initializeApp(firebaseConfig);
const auth = getAuth(app);
const storage = getStorage();
const db = getFirestore();

export { db, auth, storage };

Creating a Form to Submit Data

Now that Firebase is set up, let’s create a form component (/src/components/NewPost.jsx) that allows users to submit data to Firestore. This component uses the react-hook-form library for form handling and generates a unique identifier using the uuid library.

// /src/components/NewPost.jsx
"use client";
import { useForm } from "react-hook-form";
import { doc, setDoc } from "firebase/firestore";
import { db } from "../../lib/firebase-config";
import { v4 as uid } from "uuid";
const NewPost = () => {
  const { register, handleSubmit, reset } = useForm();

  const onSubmit = async (data) => {
    const uuid = uid();

    await setDoc(doc(db, "posts", uuid), {
      ...data,
    });

    // Clear form data and reset input fields
    reset();
  };
  return (
    <>
      <div className="relative py-3 sm:max-w-xl sm:mx-auto">
        <div className="absolute inset-0 bg-gradient-to-r from-blue-300 to-blue-600 shadow-lg transform -skew-y-6 sm:skew-y-0 sm:-rotate-6 sm:rounded-3xl"></div>
        <div className="relative px-4 py-10 bg-white shadow-lg sm:rounded-3xl sm:p-20">
          <form className="max-w-md mx-auto" onSubmit={handleSubmit(onSubmit)}>
            <div>
              <h1 className="text-2xl font-semibold">Send Data to Firebase</h1>
            </div>
            <div className="divide-y divide-gray-200">
              <div className="py-8 text-base leading-6 space-y-4 text-gray-700 sm:text-lg sm:leading-7">
                <div className="relative">
                  <input
                    autoComplete="off"
                    id="title"
                    name="title"
                    type="text"
                    className="peer placeholder-transparent h-10 w-full border-b-2 border-gray-300 text-gray-900 focus:outline-none focus:borer-rose-600"
                    placeholder=""
                    {...register("title")}
                  />
                  <label
                    htmlFor="title"
                    className="absolute left-0 -top-3.5 text-gray-600 text-sm peer-placeholder-shown:text-base peer-placeholder-shown:text-gray-440 peer-placeholder-shown:top-2 transition-all peer-focus:-top-3.5 peer-focus:text-gray-600 peer-focus:text-sm"
                  >
                    Title
                  </label>
                </div>
                <div className="relative">
                  <label
                    htmlFor="text"
                    className="block mb-2 text-sm font-medium text-gray-900 dark:text-white"
                  >
                    Your message
                  </label>
                  <textarea
                    id="text"
                    rows="3"
                    cols={40}
                    {...register("text")}
                    placeholder="write your text..."
                    className="peer  w-full border-b-2 border-gray-300 text-gray-900 focus:outline-none focus:borer-rose-600"
                  ></textarea>
                </div>

                <div className="relative">
                  <button className="bg-blue-500 text-white rounded-md px-2 py-1">
                    Submit
                  </button>
                </div>
              </div>
            </div>
          </form>
        </div>
      </div>
    </>
  );
};

export default NewPost;

Integrating Firebase in the React App

Now, let’s integrate the NewPost component into our main app (/src/app/page.js). This file acts as the entry point for our React application.

// /src/app/page.js
import NewPost from "@/components/NewPost";
export default async function Home() {
  return (
    <main className="flex min-h-screen flex-col items-center justify-between p-24">
      <NewPost />
    </main>
  );
}

Conclusion

With these steps, you’ve successfully set up Firebase in your React project and created a simple form to submit data to Firebase Firestore. This is just a starting point, and you can extend the functionality by adding features such as authentication, real-time updates, and more. Firebase’s seamless integration with React makes it a powerful tool for building dynamic and responsive web applications. Happy coding!

Nextjs
Tailwind Css
React
Firebase
Web Development
Recommended from ReadMedium