DEV Community

mike
mike

Posted on

Building a Wedding Website with Next.js, Supabase, and Tailwind CSS

Introduction

In this blog post, I'll share the journey of building a wedding website that includes an RSVP form for our guests. The main goal was to create a straightforward but functional website that allows guests to submit their RSVPs, provide any relevant notes, and request printed invitations. The tech stack consists of Next.js, Supabase, and Tailwind CSS, creating a fast, responsive, and scalable web app.

Tech Stack

  • Next.js: A React-based framework for server-side rendering and routing.
  • Supabase: For backend services like authentication, database management, and hosting.
  • Tailwind CSS: A utility-first CSS framework that provides flexibility while keeping the UI clean and customizable.
  • Cypress: Used for testing the form and ensuring everything works smoothly across all submissions.

Phase 1: Setting Up the RSVP Form

The main functionality on the wedding website is the RSVP form. The form collects guest information such as name, mobile number, email address, and RSVP status (attending or not). Additionally, guests can choose to request a printed invitation, available only to residents in the Philippines.

The form includes:

  • Basic fields: Name, mobile number, email, RSVP status, and notes.
  • Address fields: Guests can enter their address if they opt for a printed invitation.
  • Validation: Using React Hook Form for form handling and validation, we ensure:
    • Mobile numbers are validated based on the guest’s residency (Philippine vs. international).
    • Email addresses are validated if provided.
  • Confirmation Message: After submitting the form, guests are shown a success message indicating whether their RSVP was recorded or updated.

Here’s a sample of the form structure:

<div className="mb-4">
  <label htmlFor="email" className="block text-gray-700">Email (Optional)</label>
  <input
    type="text"
    {...register('email', {
      validate: value => value === '' || /^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(value) || 'Invalid email address',
    })}
    className="w-full px-4 py-2 border rounded focus:outline-none focus:ring text-black"
  />
  {errors.email && <p className="text-red-500 text-xs">{errors.email.message}</p>}
</div>
Enter fullscreen mode Exit fullscreen mode

Key Features:

  • Printed Invitations: Guests can request a printed invitation. A confirmation message will show that printed invitations are optional and available only for Philippine residents. All guests who provide an email address will receive a digital invitation.
  • Mobile Number Validation: For Philippine residents, we validate mobile numbers in both short and long formats, while also allowing international numbers.

Phase 2: Integration with Supabase

For handling form submissions, we integrated Supabase to store RSVP data. When guests submit their information, the data is saved in the rsvps table within Supabase. The process includes:

  1. Checking for Existing RSVP:
    We check if a submission with the same mobile number already exists. If it does, we update the entry. If not, we insert a new RSVP record.

  2. Database Structure:
    The rsvps table contains fields like name, mobile, email, status, and notes. We also use an auto-incrementing id for entries.

-- Reset ID counter and truncate rsvps table
TRUNCATE TABLE rsvps RESTART IDENTITY CASCADE;
Enter fullscreen mode Exit fullscreen mode

This command truncates the rsvps table and resets the ID counter to 1, which is useful for starting fresh with test data or after a significant update.

  1. Supabase Policies: To maintain data integrity and security, we implemented Row-Level Security (RLS) policies to control who can view, insert, or modify data in the rsvps table.

Phase 3: Testing with Cypress

To ensure the form works correctly, we used Cypress for end-to-end testing. We tested several important scenarios, such as:

  • Form Submission: Ensuring the correct confirmation message is shown after a successful submission (either new or update).
  • Field Validation: Verifying that the form shows error messages when invalid data is entered.
  • Handling Duplicate Submissions: Confirming that if a guest submits the same mobile number again, the system updates the existing RSVP, rather than creating a new one.

Here is an example of a Cypress test for new submissions:

it('submits the form successfully for a new submission', () => {
  cy.visit(baseUrl);

  // Submit the form with unique data
  fillForm('Jade', '+639123456783', 'michael@example.com', 'attending', 'No dietary restrictions', true, {
    address_line1: '123 Main Street',
    barangay: 'Sta Ana',
    city: 'Manila',
    province: 'Metro Manila',
    postal_code: '1000',
  });

  cy.contains('Submit').click();
  cy.contains('Thank you for RSVP-ing!').should('be.visible');
});
Enter fullscreen mode Exit fullscreen mode

Conclusion

By combining Next.js, Supabase, Tailwind CSS, and Cypress, we were able to build a robust and user-friendly wedding RSVP website. This solution allows guests to RSVP, submit their information, and handle updates as needed, all while ensuring data is stored securely and correctly. Additionally, Cypress testing ensures the website functions as expected and provides a seamless user experience.

I hope this guide is helpful to others looking to build their own wedding websites or similar projects. Stay tuned for future improvements, including styling updates and additional features!


Next Steps:

  • Styling: Customize the website with more personal designs, icons, and theme-specific colors.
  • Deployment: Host the website on Vercel or any preferred platform.

Feel free to reach out if you have any questions or need further help on your project!

Top comments (0)