Next.jsReactAdmin dashboard

Contact-Hub — Next.js Admin dashboard Template

By Oluwaseg

Contact Hub is a self-hosted contact form backend service. Multiple projects send messages to one place via API, managed centrally through a dashboard, with notifications via email, Discord, or Telegram.

Explore the design

Compare the page layouts and mobile experience. Open any screenshot for a closer look.

2 previews
Desktop homepage1 / 2
Desktop captureTop of page

Actual screenshot captured by the server browser.

All pages & views 2

Screenshots show visual appearance; interactive behavior may differ.

Recorded 2026-10-15View source

What stands out

A quick read of the recorded project description.

01

Multiple projects send contact messages to the same service via per-project API keys, with messages tagged by project

02

Admin dashboard supports login, inbox, search, tags, archiving, and bulk actions

03

New messages can trigger email, Discord webhook, or Telegram bot notifications; unconfigured providers are skipped

04

Email notifications use @unlayer/react-elements templates; the same template can render email HTML and a web preview

05

Provides project management and API key rotation interfaces

06

Rate limiting, analytics, attachment support, and reCAPTCHA listed in the README are planned features and are not yet stated as implemented

Template Details

Contact Hub solves the problem of each project repeatedly building its own contact form backend. Each project sends contact messages to Contact Hub, where messages are tagged by project and stored centrally, and administrators can view, search, and filter them in the dashboard. When a new message arrives, notifications can be sent via email, Discord webhook, or Telegram bot. Email notifications use @unlayer/react-elements templates, where the same JSX content can output both email HTML and a responsive web preview. The README states that the public landing page runs without configuration, but the dashboard and notification features require configuring .env yourself, including the database, admin password, and at least one notification provider. The project is built full-stack with Next.js App Router, using PostgreSQL (Neon), Prisma ORM, Zod validation, and Nodemailer (Gmail) for sending email, deployed on Vercel. The README roadmap lists completed and planned features; planned items include rate limiting, analytics, AI spam classification, attachment support, reCAPTCHA, and team accounts, which are not yet described in the README as implemented.

Next.jsBackend

Is it right for your project?

Use Cases

  • Receive contact form messages centrally for personal portfolios, side projects, or SaaS products
  • Filter, search, and archive contact messages by project in the dashboard
  • Get instant notification of new contact requests via email, Discord, or Telegram
  • Preview email and web rendering of notification emails in the dashboard

Suitable For

  • Independent developers with multiple projects who want to manage contact messages centrally
  • Teams or individuals who want to self-host the contact form backend and control their data
  • Developers using the Next.js, PostgreSQL, and Prisma stack

Getting started & customization

Use these recorded setup notes alongside the repository instructions for your chosen version.

  1. 1

    After cloning the repository, run pnpm install, copy .env.example to .env, and fill in the database, admin password, and at least one notification provider

  2. 2

    Run pnpm prisma migrate dev to initialize the database, then run pnpm dev

  3. 3

    Visit http://localhost:3000, log in at /login, and submit a test message via the contact API

  4. 4

    The public landing page runs without configuration; the dashboard and notification features require completing .env configuration

  5. 5

    For complete environment variables and setup steps, see SETUP.md in the repository

Read repository instructions

License & source material

Usage conditions & limitations

Free to use · keep license notice

This entry covers the free version under the MIT license in the public repository; the free scope is the code of this version and does not mean external services or third-party assets are free.

Must comply with when using

  • Free use, modification, commercial use, and distribution of this version's code are permitted.
  • When distributing copies or substantial portions of the code, retain the original author's copyright notice and the full MIT license notice.
  • The code is provided as is; warranties and limitations of liability are governed by the original license and applicable law.

Additional costs & items to verify

  • The README mentions the Formspree form service; real submissions require configuring a service endpoint, and its usage quotas and fees must be checked separately.
  • Demo images, fonts, icons, and other third-party assets must be checked under their respective licenses and cannot be judged solely by the code's MIT license.
  • External services such as domains, hosting, databases, payments, or AI may incur additional charges.
  • The public landing page runs without configuration, but the dashboard and notification features require configuring .env yourself, including the database, admin password, and at least one notification provider.
  • One or more notification providers must be configured in .env; unconfigured providers are skipped.
  • Email notifications are sent via Gmail and Nodemailer, requiring the corresponding email credential configuration.
  • Discord notifications rely on webhooks, which must be created and configured yourself.
  • Telegram notifications rely on a bot, which must be created and configured yourself.
  • Uses a PostgreSQL database, mentioned in the README as provided via Neon, requiring the corresponding database service.
  • The README lists Vercel as the hosting platform; deployment may require a Vercel account.
View Original Text Basis

Permission is hereby granted, free of charge

Original License Text

> The public landing page works out of the box. The dashboard and notifications require your own `.env` (database, admin password, and at least one notification provider).

Original README

Configure one or more providers in `.env`. The app skips any provider that isn't set up.

Original README

- **Email** (Gmail via Nodemailer), rendered with the Elements template

Original README

- **Discord** (webhook)

Original README

- **Telegram** (bot)

Original README

- **PostgreSQL** via **Neon**

Original README

- **Vercel** for hosting

Original README
https://github.com/Oluwaseg/Contact-Hub/blob/main/LICENSEhttps://github.com/Oluwaseg/Contact-Hub/blob/main/README.md

Compiled by DeepSeek based on repository license and README ·2026-10-15. Results only cover the materials read; dependencies, images, fonts, and subsequent term changes are subject to their respective original texts.

Project checks & description sources

Template Information

Source platforms
GitHub
Documentation and maintenance reference score
More documented · 80 / 100
Technologies
Next.js · React
Website type
Admin dashboard
How this score is calculated

Our heuristic uses license records (up to 30), a demo link (12), a preview (10), stars (15), recorded maintenance (15), description completeness (8), feature records (5) and classification data (5). It is not a code, security or performance test, or a Google score. A link does not establish tested functionality.

What to verify for this project

Repository update recorded
2026-07-22
Screenshot last checked
2026-10-15

A demo link is listed. Check it with your own content and viewport sizes; its presence does not confirm that forms, authentication or payments work.

The catalog identifies Next.js as the primary stack. Check the actual dependency manifest and lockfile for versions and hosting requirements. These notes use recorded metadata, not a code audit or a deployment test.

Use a selection guide →

How this description was prepared

AI-assisted description based on catalog records and repository material. Repository authors are not automatically the reviewers of this description.

Review declaration: codex-user-requested-batch-review-20261017 · 2026-10-16

Inspect the recorded source material

SHA-256: 09c9f752842291f50ae1698b062a6f275cdccb881c2596afda2509b9e973bc43

2026-10-15T11:08:28.751Z

Source file / repository
# Contact Hub

**Stop rebuilding contact form backends for every side project.**

[![Built with Elements](https://img.shields.io/badge/Built%20with-Elements-0D9488?style=flat-square)](https://github.com/unlayer/elements)
[![License: MIT](https://img.shields.io/badge/License-MIT-blue?style=flat-square)](LICENSE)

**Repo:** https://github.com/Oluwaseg/Contact-Hub

---

## The Problem

If you build a few different apps or sites (a portfolio, a SaaS product, a side project), each one usually ends up with its own scattered way of handling "someone wants to reach me."

Maybe it's a mailto link. Maybe it's a form that quietly emails a Gmail you forget to check. Maybe you find out three weeks later that someone tried to contact you about one of your apps, but the message went to the wrong inbox and got buried.

Multiply that across every project you build, and you get a mess: no single place to see who's reached out, when, or about what.

## The Idea

Contact Hub is a small, single service that every one of your projects talks to.

Instead of each app building (and re-building) its own contact form backend, they all send their messages to one place. Contact Hub stores them, can notify you through configurable providers such as Discord, Telegram, or email, and gives you one dashboard to see everything at a glance, filterable by project.

Think of it as your own private, self-hosted, open-source version of Formspree. Built once, owned entirely by you, and reusable forever.

**Example use case** (the project names below are just some of my own apps that talk to Contact Hub):

One side project gets a feature request. Another gets a partnership inquiry. Your portfolio gets a freelance lead. Instead of checking three different inboxes, every message lands in Contact Hub, tagged by project, in one place.

## How It Fits Together

```
Portfolio         ──┐
DeadLink Watchdog ──┼──►  Contact Hub  ──►  Email notification (Elements template)
WalletWise        ──┘           │
(next project...)               ▼
                          Admin dashboard
                          (message + email/web preview)
```

Every project sends its messages to Contact Hub. Contact Hub keeps a record of everything, notifies you the moment a message arrives, and shows it all in one admin dashboard (sorted, searchable, and filterable by project).

---

## Built with Unlayer Elements

Elements is a core part of this project, not a side experiment.

Contact Hub was already a real app with a real use case: I kept rebuilding contact-form backends for every project. The challenge gave me a reason to replace hand-written notification HTML with a proper, reusable template system powered by [@unlayer/react-elements](https://github.com/unlayer/elements).

### What the template does

When someone submits a contact form, Contact Hub sends a "New Contact Message Received" notification. That email is built entirely with Elements:

| Piece | Location |
|-------|----------|
| Template component | [`src/templates/ContactMessageNotification.tsx`](src/templates/ContactMessageNotification.tsx) |
| Render helpers | [`src/lib/renderContactMessageNotification.tsx`](src/lib/renderContactMessageNotification.tsx) |
| Live email sending | [`src/lib/mailer.ts`](src/lib/mailer.ts) |
| Dashboard email preview | `/dashboard/messages/[id]/email` |
| Dashboard web preview | `/dashboard/messages/[id]/web` |

### Write once, render everywhere

The same JSX content is wrapped in two Elements root components:

- `<Email>` produces table-based HTML for Gmail, Outlook, Apple Mail (used when Nodemailer sends notifications)
- `<Page>` produces responsive web HTML (shown in the dashboard's web preview)

One template. Two outputs. No duplicated markup.

```tsx
// Shared content, two render modes
<Email>...</Email>   // notification in your inbox
<Page>...</Page>     // responsive web preview in the dashboard
```

---

## Demo

[Watch the demo video](docs/videos/demo.mp4)

## Screenshots

### Message details

![Message details view](docs/screenshots/message-preview.png)

### Email preview (Elements `<Email>` mode)

![Email preview](docs/screenshots/email-preview.png)

### Web preview (Elements `<Page>` mode)

![Web preview](docs/screenshots/web-preview.png)

---

## Quick start

Full setup guide: **[SETUP.md](SETUP.md)**

```bash
git clone https://github.com/Oluwaseg/Contact-Hub.git
cd Contact-Hub
pnpm install
cp .env.example .env   # then fill in your values
pnpm prisma migrate dev
pnpm dev
```

Open `http://localhost:3000`, sign in at `/login`, and submit a test message via the contact API (see [SETUP.md](SETUP.md) for environment variables).

> The public landing page works out of the box. The dashboard and notifications require your own `.env` (database, admin password, and at least one notification provider).

---

## Notifications

Every incoming message can trigger instant notifications through configurable providers:

- **Email** (Gmail via Nodemailer), rendered with the Elements template
- **Discord** (webhook)
- **Telegram** (bot)

Configure one or more providers in `.env`. The app skips any provider that isn't set up.

## What It Solves

- **No more guessing which inbox a message landed in.** Every message is tagged with the project it came from.
- **No more rebuilding the same contact form logic for every new project.** Build it once here, reuse it everywhere.
- **One place to check.** Instead of five different "contact" systems across five different projects, there's one.
- **A record you actually keep.** Emails get lost or archived. A proper dashboard doesn't.
- **Instant alerts.** Notifications mean you find out the moment someone reaches out.

## Why it's free

Contact Hub was built to solve a problem I kept running into across my own projects. Rather than turning it into a paid SaaS, I decided to keep it open source so anyone can self-host, contribute, or adapt it.

If it saves you time or helps your projects, consider:

- Starring the repo on GitHub
- Sharing feedback or opening issues
- [Supporting development with a donation](https://selar.com/showlove/oluwaseg) (optional, never required)

I don't intend to monetize Contact Hub. It's infrastructure I wanted for myself, and I'd rather share it than gate it.

## Why build this instead of a third-party tool?

Tools like Formspree or Getform are fine, but they come with limits on free tiers, monthly costs as you scale, and no real ownership of your data. Since the goal is to reuse this across every project for years, it made more sense to own the whole thing. No usage caps, no per-project pricing, and full control over how messages are stored and displayed.

## Roadmap

```
Done:
  Core API
  Project authentication (per-project API keys)
  Email notifications (Unlayer Elements template)
  Email + web template previews in dashboard
  Basic spam protection
  Admin dashboard (login, inbox, filters)
  Project management UI (add/remove projects, rotate keys)
  Search
  Labels / tags
  Archive & bulk actions
  Webhooks (Discord / Telegram notifications)

Planned:
  Rate limiting
  Analytics (messages per project, over time)
  AI spam / auto-categorization
  Attachments support
  reCAPTCHA verification
  Team accounts (future)
```

## Tech stack

- **Next.js** (App Router, fullstack)
- **[@unlayer/react-elements](https://github.com/unlayer/elements)** for notification email + web template rendering
- **PostgreSQL** via **Neon**
- **Prisma** ORM
- **Zod** for validation
- **Nodemailer** (Gmail) for email delivery
- **Vercel** for hosting

## Contributing

See [CONTRIBUTING.md](CONTRIBUTING.md) if you want to report a bug, improve the docs, or send a pull request.

## License

MIT. See [LICENSE](LICENSE).

---

_Built by [Samuel Oluwasegun](https://github.com/Oluwaseg) as shared infrastructure for personal and portfolio projects._
Report a correction

Explore similar templates

Compare previews and descriptions within the same stack and category.