├── app ├── globals.css ├── favicon.ico ├── page.tsx └── layout.tsx ├── public ├── robots.txt ├── vercel.svg ├── window.svg ├── file.svg ├── globe.svg └── next.svg ├── postcss.config.mjs ├── next.config.ts ├── package.json ├── .gitignore ├── tsconfig.json ├── README.md ├── components ├── EmailView.tsx └── Home.tsx └── actions └── actions.ts /app/globals.css: -------------------------------------------------------------------------------- 1 | @import "tailwindcss"; 2 | 3 | -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Allow: / 3 | -------------------------------------------------------------------------------- /app/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pranavkdileep/TempMailo/HEAD/app/favicon.ico -------------------------------------------------------------------------------- /postcss.config.mjs: -------------------------------------------------------------------------------- 1 | const config = { 2 | plugins: ["@tailwindcss/postcss"], 3 | }; 4 | 5 | export default config; 6 | -------------------------------------------------------------------------------- /public/vercel.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /next.config.ts: -------------------------------------------------------------------------------- 1 | import type { NextConfig } from "next"; 2 | 3 | const nextConfig: NextConfig = { 4 | /* config options here */ 5 | }; 6 | 7 | export default nextConfig; 8 | -------------------------------------------------------------------------------- /app/page.tsx: -------------------------------------------------------------------------------- 1 | import HomePage from "@/components/Home"; 2 | 3 | 4 | export default function Home() { 5 | return ( 6 | <> 7 | 8 | 9 | ); 10 | } 11 | -------------------------------------------------------------------------------- /public/window.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/file.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tempmailo", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "next dev --turbopack", 7 | "build": "next build", 8 | "start": "next start", 9 | "lint": "next lint" 10 | }, 11 | "dependencies": { 12 | "lucide-react": "^0.513.0", 13 | "next": "15.3.3", 14 | "react": "^19.0.0", 15 | "react-dom": "^19.0.0" 16 | }, 17 | "devDependencies": { 18 | "@tailwindcss/postcss": "^4", 19 | "@types/node": "^20", 20 | "@types/react": "^19", 21 | "@types/react-dom": "^19", 22 | "tailwindcss": "^4", 23 | "typescript": "^5" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.* 7 | .yarn/* 8 | !.yarn/patches 9 | !.yarn/plugins 10 | !.yarn/releases 11 | !.yarn/versions 12 | 13 | # testing 14 | /coverage 15 | 16 | # next.js 17 | /.next/ 18 | /out/ 19 | 20 | # production 21 | /build 22 | 23 | # misc 24 | .DS_Store 25 | *.pem 26 | 27 | # debug 28 | npm-debug.log* 29 | yarn-debug.log* 30 | yarn-error.log* 31 | .pnpm-debug.log* 32 | 33 | # env files (can opt-in for committing if needed) 34 | .env* 35 | 36 | # vercel 37 | .vercel 38 | 39 | # typescript 40 | *.tsbuildinfo 41 | next-env.d.ts 42 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2017", 4 | "lib": ["dom", "dom.iterable", "esnext"], 5 | "allowJs": true, 6 | "skipLibCheck": true, 7 | "strict": true, 8 | "noEmit": true, 9 | "esModuleInterop": true, 10 | "module": "esnext", 11 | "moduleResolution": "bundler", 12 | "resolveJsonModule": true, 13 | "isolatedModules": true, 14 | "jsx": "preserve", 15 | "incremental": true, 16 | "plugins": [ 17 | { 18 | "name": "next" 19 | } 20 | ], 21 | "paths": { 22 | "@/*": ["./*"] 23 | } 24 | }, 25 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], 26 | "exclude": ["node_modules"] 27 | } 28 | -------------------------------------------------------------------------------- /app/layout.tsx: -------------------------------------------------------------------------------- 1 | import type { Metadata } from "next"; 2 | import { Geist, Geist_Mono } from "next/font/google"; 3 | import "./globals.css"; 4 | 5 | const geistSans = Geist({ 6 | variable: "--font-geist-sans", 7 | subsets: ["latin"], 8 | }); 9 | 10 | const geistMono = Geist_Mono({ 11 | variable: "--font-geist-mono", 12 | subsets: ["latin"], 13 | }); 14 | 15 | export const metadata: Metadata = { 16 | title: "TempMailo - Free Temporary Email Service", 17 | description: "Get a free, temporary email address with TempMailo. Protect your privacy and avoid spam with our disposable email service.", 18 | }; 19 | 20 | export default function RootLayout({ 21 | children, 22 | }: Readonly<{ 23 | children: React.ReactNode; 24 | }>) { 25 | return ( 26 | 27 | 30 | {children} 31 | 32 | 33 | ); 34 | } 35 | -------------------------------------------------------------------------------- /public/globe.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/next.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | > **Disclaimer:** 2 | > This project is a client-only application that uses a third-party, unofficial API: [TempMail API Free on RapidAPI](https://rapidapi.com/pranavkdileep/api/tempmail-api-free). 3 | > We are not affiliated with, authorized by, or responsible for the operation, data, or security of the API or its server. Use at your own risk. 4 | 5 | # TempMail0 Next.js App 6 | ![Screenshot from 2025-06-10 18-01-49](https://github.com/user-attachments/assets/29a5c727-d757-475a-bd05-a18cc39dc1c1) 7 | ![Screenshot from 2025-06-10 18-02-01](https://github.com/user-attachments/assets/653c3091-3854-4d19-b110-3bf023739229) 8 | 9 | 10 | 11 | 12 | This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://nextjs.org/docs/app/api-reference/cli/create-next-app). 13 | 14 | ## Getting Started 15 | 16 | First, run the development server: 17 | 18 | ```bash 19 | npm run dev 20 | # or 21 | yarn dev 22 | # or 23 | pnpm dev 24 | # or 25 | bun dev 26 | ``` 27 | 28 | Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. 29 | 30 | You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file. 31 | 32 | This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel. 33 | 34 | ## Learn More 35 | 36 | To learn more about Next.js, take a look at the following resources: 37 | 38 | - [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API. 39 | - [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. 40 | 41 | You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js) - your feedback and contributions are welcome! 42 | 43 | ## Deploy on Vercel 44 | 45 | The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js. 46 | 47 | Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details. 48 | -------------------------------------------------------------------------------- /components/EmailView.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import React from "react"; 4 | import { ArrowLeft } from "lucide-react"; 5 | 6 | interface EmailViewProps { 7 | email: { 8 | id: string; 9 | from: string; 10 | to: string; 11 | cc: string; 12 | subject: string; 13 | body_text: string; 14 | body_html: string; 15 | created_at: string; 16 | isRead: boolean; 17 | isUnread?: boolean; 18 | }; 19 | onBack: () => void; 20 | } 21 | 22 | function EmailView({ email, onBack }: EmailViewProps) { 23 | return ( 24 |
25 |
26 |
27 | 34 |
35 |
36 |

37 | Subject: {email.subject} 38 |

39 |
40 |
41 | From: 42 | {email.from} 43 |
44 |
45 | To: 46 | {email.to} 47 |
48 | {email.cc && ( 49 |
50 | CC: 51 | {email.cc} 52 |
53 | )} 54 |
55 | Date: 56 | {email.created_at} 57 |
58 |
59 |
60 | {email.body_html ? ( 61 |
62 | ) : ( 63 |
{email.body_text}
64 | )} 65 |
66 |
67 |
68 |
69 | ); 70 | } 71 | 72 | export default EmailView; -------------------------------------------------------------------------------- /actions/actions.ts: -------------------------------------------------------------------------------- 1 | "use server"; 2 | import { cookies } from "next/headers"; 3 | 4 | const baseUrl = process.env.BASE_URL || "https://tempmail-api-free.p.rapidapi.com"; 5 | const x_rapidapi_key = process.env.X_RAPIDAPI_KEY || "50c9c3f974msh08092f88f044eedp10a9f2jsnfaf6222bc9c6"; 6 | const x_rapidapi_host = process.env.X_RAPIDAPI_HOST || "tempmail-api-free.p.rapidapi.com"; 7 | 8 | interface Email { 9 | id: string; 10 | from: string; 11 | to: string; 12 | cc: string; 13 | subject: string; 14 | body_text: string; 15 | body_html: string; 16 | created_at: string; 17 | isRead: boolean; 18 | isUnread?: boolean; 19 | } 20 | 21 | export const getcurrentEmail = async () => { 22 | try { 23 | const currentemail = (await cookies()).get("currentemail"); 24 | if (!currentemail) { 25 | const newemail = await registerEmail(); 26 | return newemail; 27 | } 28 | return currentemail!.value; 29 | } catch (error) { 30 | console.error("Error fetching current email:", error); 31 | throw new Error("Failed to fetch current email"); 32 | } 33 | } 34 | 35 | export const registerEmail = async (name: string = Math.random().toString(36).substring(2, 8)) => { 36 | try { 37 | const domains = await getDomains(); 38 | const randomDomain = domains[Math.floor(Math.random() * domains.length)]; 39 | const response = await fetch(`${baseUrl}/api/v3/email/new`, { 40 | method: 'POST', 41 | headers: { 42 | 'x-rapidapi-key': x_rapidapi_key, 43 | 'x-rapidapi-host': x_rapidapi_host, 44 | 'Content-Type': 'application/json' 45 | }, 46 | body: JSON.stringify({ 47 | name: name, 48 | domain: randomDomain.name 49 | }) 50 | } 51 | ); 52 | const data = await response.json(); 53 | console.log(data) 54 | if (!response.ok) { 55 | throw new Error("Failed to register email"); 56 | } 57 | 58 | if (!data.email) { 59 | throw new Error("No email returned from API"); 60 | } 61 | const currentemail = data.email; 62 | const currenttoken = data.token; 63 | const cookieStore = await cookies(); 64 | cookieStore.set("currentemail", currentemail,{ maxAge: 60 * 60 * 24 * 30 }); 65 | cookieStore.set("currenttoken", currenttoken,{ maxAge: 60 * 60 * 24 * 30 }); 66 | return currentemail; 67 | } catch (error) { 68 | console.error("Error registering email:", error); 69 | throw new Error("Failed to register email"); 70 | } 71 | } 72 | 73 | export const deletecurrentEmail = async () => { 74 | try { 75 | const currentemail = (await cookies()).get("currentemail"); 76 | const currenttoken = (await cookies()).get("currenttoken"); 77 | if (!currentemail || !currenttoken) { 78 | throw new Error("No current email or token found"); 79 | } 80 | const response = await fetch(`${baseUrl}/api/v3/email/${currentemail.value}`, { 81 | method: 'DELETE', 82 | headers: { 83 | 'x-rapidapi-key': x_rapidapi_key, 84 | 'x-rapidapi-host': x_rapidapi_host, 85 | 'Content-Type': 'application/json' 86 | }, 87 | body: JSON.stringify({ 88 | token: currenttoken.value 89 | }) 90 | } 91 | ); 92 | if (!response.ok) { 93 | throw new Error("Failed to delete email"); 94 | } 95 | const cookieStore = await cookies(); 96 | cookieStore.delete("currentemail"); 97 | cookieStore.delete("currenttoken"); 98 | return true; 99 | } catch (error) { 100 | const cookieStore = await cookies(); 101 | cookieStore.delete("currentemail"); 102 | cookieStore.delete("currenttoken"); 103 | return true; 104 | } 105 | } 106 | 107 | export const getEmails = async (email: string) => { 108 | try { 109 | const response = await fetch(`${baseUrl}/api/v3/email/${email}/messages`, { 110 | method: 'GET', 111 | headers: { 112 | 'x-rapidapi-key': x_rapidapi_key, 113 | 'x-rapidapi-host': x_rapidapi_host 114 | } 115 | }); 116 | let data = await response.json(); 117 | console.log(data); 118 | if (!response.ok) { 119 | throw new Error("Failed to fetch emails"); 120 | } 121 | 122 | 123 | if (!data || data.length === 0) { 124 | throw new Error("No emails found"); 125 | } 126 | // data = data.map((email: Email) => ({ 127 | // ...email, 128 | // isUnread: true, 129 | // })); 130 | data.sort((a: Email, b: Email) => new Date(b.created_at).getTime() - new Date(a.created_at).getTime()); 131 | return data; 132 | } catch (error) { 133 | console.error("Error fetching emails:", error); 134 | throw new Error("Failed to fetch emails"); 135 | } 136 | } 137 | 138 | export const getDomains = async () => { 139 | try { 140 | const response = await fetch(`${baseUrl}/api/v3/domains`, { 141 | method: 'GET', 142 | headers: { 143 | 'x-rapidapi-key': x_rapidapi_key, 144 | 'x-rapidapi-host': x_rapidapi_host 145 | } 146 | }); 147 | 148 | if (!response.ok) { 149 | throw new Error("Failed to fetch domains"); 150 | } 151 | 152 | const data = await response.json(); 153 | if (!data.domains || data.domains.length === 0) { 154 | throw new Error("No domains found"); 155 | } 156 | return data.domains; 157 | } catch (error) { 158 | console.error("Error fetching domains:", error); 159 | throw new Error("Failed to fetch domains"); 160 | } 161 | } 162 | -------------------------------------------------------------------------------- /components/Home.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import React, { useState, useEffect } from "react"; 4 | import { 5 | Copy, 6 | Check, 7 | RefreshCw, 8 | Trash2, 9 | Github, 10 | Menu, 11 | MailOpen, 12 | MailCheck, 13 | } from "lucide-react"; 14 | import EmailView from "./EmailView"; 15 | import { 16 | deletecurrentEmail, 17 | getcurrentEmail, 18 | getEmails, 19 | registerEmail, 20 | } from "@/actions/actions"; 21 | 22 | import Image from "next/image"; 23 | 24 | interface Email { 25 | id: string; 26 | from: string; 27 | to: string; 28 | cc: string; 29 | subject: string; 30 | body_text: string; 31 | body_html: string; 32 | created_at: string; 33 | isRead: boolean; 34 | isUnread?: boolean; 35 | } 36 | 37 | function HomePage() { 38 | const [currentEmail, setCurrentEmail] = useState("loading..."); 39 | const [selectedEmail, setSelectedEmail] = useState(null); 40 | const [emails, setEmails] = useState([]); 41 | const [loadingGenerate, setLoadingGenerate] = useState(false); 42 | const [loadingDelete, setLoadingDelete] = useState(false); 43 | const [loadingEmails, setLoadingEmails] = useState(true); 44 | const [isCopied, setIsCopied] = useState(false); 45 | 46 | useEffect(() => { 47 | setLoadingGenerate(true); 48 | getcurrentEmail() 49 | .then((email) => { 50 | console.log("Current email:", email); 51 | setCurrentEmail(email); 52 | }) 53 | .catch((error) => { 54 | console.error("Error fetching current email:", error); 55 | setCurrentEmail("Failed to load email"); 56 | }); 57 | setLoadingGenerate(false); 58 | }, []); 59 | useEffect(() => { 60 | if(!currentEmail || currentEmail === "loading...") return; 61 | getEmails(currentEmail) 62 | .then((emails) => { 63 | console.log("Fetched emails:", emails); 64 | setEmails(emails); 65 | setLoadingEmails(false); 66 | }) 67 | .catch((error) => { 68 | console.error("Error fetching emails:", error); 69 | setEmails([]); 70 | setLoadingEmails(false); 71 | }); 72 | }, [currentEmail]); 73 | 74 | useEffect(() => { 75 | if (isCopied) { 76 | const timer = setTimeout(() => { 77 | setIsCopied(false); 78 | }, 2000); 79 | return () => clearTimeout(timer); 80 | } 81 | }, [isCopied]); 82 | 83 | const generateNewEmail = async () => { 84 | setLoadingGenerate(true); 85 | const randomString = Math.random().toString(36).substring(2, 8); 86 | const newemail = await registerEmail(randomString); 87 | setCurrentEmail(newemail); 88 | setLoadingGenerate(false); 89 | }; 90 | 91 | const copyToClipboard = () => { 92 | navigator.clipboard.writeText(currentEmail).then(() => { 93 | setIsCopied(true); 94 | console.log("Email copied to clipboard:", currentEmail); 95 | }).catch((error) => { 96 | console.error("Failed to copy email:", error); 97 | }); 98 | }; 99 | 100 | const deleteEmail = async () => { 101 | await deletecurrentEmail(); 102 | setCurrentEmail(""); 103 | setSelectedEmail(null); 104 | setEmails([]); 105 | }; 106 | 107 | const handleEmailClick = (email: Email) => { 108 | setSelectedEmail(email); 109 | }; 110 | 111 | const handleBackToInbox = () => { 112 | setSelectedEmail(null); 113 | }; 114 | 115 | if (selectedEmail) { 116 | return ( 117 |
118 |
119 | {/* Header */} 120 |
121 |
122 |
123 | TempMailo Logo - Temporary Email Service 129 |
130 |

131 | TempMailo 132 |

133 |
134 | 142 | 145 |
146 | 147 | 148 | 149 | {/* Footer */} 150 |
151 |

152 | © 2025 TempMailo. All rights reserved. 153 |

154 |
155 |
156 |
157 | ); 158 | } 159 | 160 | return ( 161 |
162 |
163 | {/* Header */} 164 |
165 |
166 |
167 | TempMailo Logo - Temporary Email Service 173 |
174 |

175 | TempMailo 176 |

177 |
178 | 186 | 189 |
190 | 191 | {/* Main Content */} 192 |
193 |
194 | {/* Email Address Section */} 195 |
196 |

197 | Your Temporary Email Address 198 |

199 |
200 |
201 |
202 | 208 | 219 |
220 |
221 |
222 | 229 | 236 |
237 |
238 |
239 | 240 | {/* Inbox Section */} 241 |
242 |
243 |

244 | Inbox 245 |

246 | 264 |
265 | {!loadingEmails ? <> 266 | { emails.length != 0 ? (
267 | {emails.map((email) => ( 268 |
handleEmailClick(email)} 272 | > 273 |
280 | {email.isUnread ? ( 281 | 282 | ) : ( 283 | 284 | )} 285 |
286 |
287 |

294 | {email.from} 295 |

296 |

297 | {email.subject} 298 |

299 |
300 |
301 |

302 | {email.created_at} 303 |

304 | {email.isUnread && ( 305 | 306 | 1 307 | 308 | )} 309 |
310 |
311 | ))} 312 |
):( 313 |
314 |

No emails found.

315 |
316 | )} 317 | :( 318 |
319 |

Loading emails...

320 |
321 | )} 322 |
323 |
324 |
325 | 326 | {/* Footer */} 327 | 332 |
333 |
334 | ); 335 | } 336 | 337 | export default HomePage; 338 | --------------------------------------------------------------------------------