Certify is a robust web application designed to streamline the issuance, management, and verification of digital certificates. Built with the MERN stack (MongoDB, Express.js, React, Node.js), it provides a secure and user-friendly environment for organizations and individuals to handle credentials efficiently.
What it is: A secure system for user identity and session management. How it works:
- Dual Login: Users can register via Email/Password (hashed with bcrypt for security) or Google OAuth (using Passport.js).
- Session Management: Upon login, a JWT (JSON Web Token) is issued and stored securely in the browser's
localStorage. - Protected Routes: React Router middleware checks for this token before allowing access to private pages like the Dashboard or Settings.
- Safe Storage: The app includes a fail-safe mechanism to handle environments where
localStorageis blocked (e.g., strict privacy settings), ensuring the app doesn't crash.
What it is: The core module for uploading, organizing, and maintaining digital credentials. How it works:
- File Upload: Users can drag-and-drop certificate files (Images or PDFs). These are uploaded securely to Supabase Storage buckets.
- Smart Metadata: Users attach details like Issuer, Issue Date, Categories, and Tags.
- Unique Slugs: The system automatically generates a URL-friendly "slug" (e.g.,
advanced-react-certification) for every certificate, making sharing easy. - Visibility Controls:
- Public: The certificate appears on your Public Profile and is verifiable by anyone.
- Private: Only you can see it in your dashboard.
- Unlisted: It doesn't show on your profile, but anyone with the direct link can view it (perfect for sharing with specific employers).
What it is: A trustless way for third parties (employers, schools) to verify the authenticity of a certificate. How it works:
- Direct Links: Each certificate gets a permanent, unique URL (e.g.,
/public/:username/:slug). - No Login Required: Verifiers do not need a Certify account to view public or unlisted certificates.
- Secure Access: When a public certificate is requested, the backend generates a time-limited Signed URL from Supabase, ensuring the actual file storage remains private and secure.
- File Proxy: Certificate files are served through a secure proxy endpoint (
/api/public/file/:username/:slug) that validates permissions before streaming the content.
What it is: A personal portfolio page showcasing all your public achievements. How it works:
- Vanity URL: Every user gets a profile at
/u/username. - Dynamic Content: The profile automatically fetches and displays only certificates marked as "Public".
- Customization: In Settings, users can:
- Toggle their entire profile to "Private" (disabling the public link).
- Choose their preferred layout (Grid View for visual impact, List View for density).
- Update username with a clean prefix display (e.g.,
certify.in/username).
What it is: Tools to display your certificates on external websites and integrate with other platforms. How it works:
- JavaScript Embed: Simple script tag integration for any website:
<script src="https://certify.in/embed.js" data-user="username" data-view="grid"></script>
- React Component (NPM Package): Install
certify-embed-reactfor seamless React integration:npm install certify-embed-react
import CertificateGallery from "certify-embed-react"; <CertificateGallery username="yourname" view="grid" />
- Public REST API: Fetch user certificates programmatically:
Returns JSON with certificate data including title, issuer, date, category, and image URLs.
GET /api/public/user/:username/certificates - CORS Enabled: All public endpoints support cross-origin requests for easy integration.
What it is: A polished, responsive interface designed for usability. How it works:
- Responsive Design: Built with Tailwind CSS, the layout adapts fluidly from mobile phones to large desktop screens.
- Dark Mode: A global theme toggle (Light/Dark/System) persists user preference in local storage and instantly updates the UI using CSS variables.
- Instant Feedback: Asynchronous actions (like uploading or saving) trigger Toast Notifications (Success/Error alerts) and display loading skeletons to keep the user informed.
- Smooth Animations: Powered by Framer Motion for fluid transitions and micro-interactions.
- React.js 18 - Modern UI library with hooks
- Vite - Lightning-fast build tool and dev server
- Tailwind CSS - Utility-first CSS framework
- Zustand - Lightweight state management
- Axios - HTTP client with interceptors
- React Router - Client-side routing
- Framer Motion - Animation library
- Lucide React - Beautiful icon set
- Vercel Analytics - Performance monitoring
- Node.js - JavaScript runtime
- Express.js - Web application framework
- MongoDB & Mongoose - NoSQL database and ODM
- Passport.js - Authentication middleware (Google OAuth)
- JWT - Secure token-based authentication
- Bcrypt - Password hashing
- Multer - File upload handling
- Supabase Storage - Cloud file storage
- Slugify & Nanoid - URL-friendly identifiers
- Vercel - Frontend hosting with edge functions
- Render - Backend hosting
- MongoDB Atlas - Managed database service
- NPM - Package registry for
certify-embed-react
- Node.js 16+ and npm
- MongoDB Atlas account
- Supabase account
- Google OAuth credentials (optional)
MONGO_URI=your_mongodb_connection_string
JWT_SECRET=your_jwt_secret_key
SUPABASE_URL=your_supabase_url
SUPABASE_KEY=your_supabase_anon_key
SUPABASE_BUCKET=certificates
GOOGLE_CLIENT_ID=your_google_oauth_client_id
GOOGLE_CLIENT_SECRET=your_google_oauth_client_secret
GOOGLE_CALLBACK_URL=http://localhost:5000/api/auth/google/callback
CLIENT_URL=http://localhost:5173
PORT=5000VITE_API_URL=http://localhost:5000
VITE_GOOGLE_CLIENT_ID=your_google_oauth_client_id-
Clone the repository
git clone https://github.com/SumantSagar73/certify.git cd certify -
Install dependencies
# Install root dependencies npm install # Install backend dependencies cd server npm install # Install frontend dependencies cd ../client npm install
-
Set up environment variables
- Create
.envfiles in bothserver/andclient/directories - Fill in the values as shown above
- Create
-
Run the development servers
# Terminal 1 - Backend (from server/) npm run dev # Terminal 2 - Frontend (from client/) npm run dev
-
Access the application
- Frontend:
http://localhost:5173 - Backend API:
http://localhost:5000
- Frontend:
- Push your code to GitHub
- Import project in Vercel dashboard
- Set root directory to
client - Add environment variable:
VITE_API_URL=https://your-backend-url.onrender.com
- Deploy
- Create a new Web Service
- Connect your GitHub repository
- Set root directory to
server - Add all environment variables from
server/.env - Set build command:
npm install - Set start command:
npm start - Deploy
- Local Development: Vite proxies
/apirequests tolocalhost:5000(configured invite.config.js) - Production: Frontend makes direct requests to the backend URL via
VITE_API_URL
GET /api/public/user/:username/certificates
Response:
{
"username": "Nitin Mishra",
"totalCount": 5,
"certificates": [
{
"title": "React Advanced Certification",
"issuer": "Meta",
"date": "2024-01-15",
"category": "Web Development",
"imageUrl": "https://...",
"slug": "react-advanced-certification"
}
]
}GET /api/public/:username/:slug
GET /api/public/file/:username/:slug
POST /api/certificates
Authorization: Bearer <token>
Content-Type: multipart/form-data
Fields: title, issuer, issueDate, category, tags, visibility, file
GET /api/certificates
Authorization: Bearer <token>
PATCH /api/certificates/:id
Authorization: Bearer <token>
DELETE /api/certificates/:id
Authorization: Bearer <token>
Embed Certify certificates in your React applications.
npm install certify-embed-reactimport CertificateGallery from 'certify-embed-react';
function MyPortfolio() {
return (
<CertificateGallery
username="yourname"
view="grid"
apiBaseUrl="https://certify-backend.onrender.com"
/>
);
}username(required): Certify usernameview:"grid"|"list"(default:"grid")apiBaseUrl(optional): Custom API base URL
Contributions are welcome! Please feel free to submit a Pull Request.
This project is licensed under the MIT License.
For questions or support, please open an issue on GitHub.