NextJS Templates
Building the Ticketing App with Next.js, Vercel and Back4App
30 min
in this tutorial, we'll build a ticketing system using next js with the app router, back4app as the backend service, and tailwind css for styling the app allows users to create, update, view, and delete tickets, while utilizing parse server on back4app for database management 1\ prerequisites before starting, make sure you have node js installed on your machine ( node js installation guide https //nodejs org/ ) back4app account ( sign up for free https //www back4app com/ ) vercel account for deployment ( sign up for vercel https //vercel com/ ) 2\ setting up back4app log in to your back4app dashboard and create a new project navigate to the data browser and create a new class called ticket with the following schema field name type title string description string category string priority number progress number status string createdat date (auto generated) updatedat date (auto generated) 3\ setting up the frontend (next js) 3 1 create a new next js project run the following command to create a new next js project npx create next app\@latest ticketing app cd ticketing app 3 2 install dependencies install tailwind css , font awesome , and parse sdk for backend operations npm install tailwindcss postcss autoprefixer @fortawesome/fontawesome free parse npx tailwindcss init p 3 3 set up tailwind css edit the tailwind config js file to configure the tailwind css content paths module exports = { content \[ ' /app/ / {js,ts,jsx,tsx}', ' /components/ / {js,ts,jsx,tsx}', ], theme { extend {}, }, plugins \[], } in styles/globals css , add the tailwind imports @tailwind base; @tailwind components; @tailwind utilities; 3 4 create the project structure following the structure provided, create the necessary directories and components directory structure /app /tickets /\[id] page js layout js page js /components deleteblock jsx nav jsx prioritydisplay jsx progressdisplay jsx statusdisplay jsx ticketcard jsx ticketform jsx /lib parseclient js 4\ setting up parse client in the /lib folder, create a parseclient js file to configure the parse sdk import parse from 'parse'; // initialize parse sdk parse initialize('your app id', 'your js key'); parse serverurl = 'https //parseapi back4app com'; export default parse; replace 'your app id' and 'your js key' with your back4app project credentials 5\ creating the key components 5 1 ticketform this component will handle both creating and updating tickets in /components/ticketform jsx , create the following import { usestate } from 'react'; import parse from ' /lib/parseclient'; export default function ticketform({ ticket }) { const \[title, settitle] = usestate(ticket? title || ''); const \[description, setdescription] = usestate(ticket? description || ''); const handlesubmit = async (e) => { e preventdefault(); const ticket = parse object extend('ticket'); const newticket = ticket || new ticket(); newticket set('title', title); newticket set('description', description); try { await newticket save(); alert('ticket saved successfully!'); } catch (error) { console error('error saving ticket ', error); } }; return ( \<form onsubmit={handlesubmit}> \<input type="text" value={title} onchange={(e) => settitle(e target value)} placeholder="title" required /> \<textarea value={description} onchange={(e) => setdescription(e target value)} placeholder="description" required /> \<button type="submit">save ticket\</button> \</form> ); } 5 2 ticketcard this component will display individual ticket information in /components/ticketcard jsx import link from 'next/link'; import progressdisplay from ' /progressdisplay'; export default function ticketcard({ ticket }) { return ( \<div classname="border p 4"> \<h2>{ticket title}\</h2> \<p>{ticket description}\</p> \<progressdisplay progress={ticket progress} /> \<link href={`/tickets/${ticket objectid}`}>edit\</link> \</div> ); } 5 3 deleteblock a confirmation component for deleting tickets in /components/deleteblock jsx import parse from ' /lib/parseclient'; export default function deleteblock({ ticketid, ondelete }) { const handledelete = async () => { const query = new parse query('ticket'); const ticket = await query get(ticketid); try { await ticket destroy(); alert('ticket deleted successfully'); ondelete(); } catch (error) { console error('error deleting ticket ', error); } }; return ( \<button onclick={handledelete}>delete ticket\</button> ); } 5 4 progressdisplay this component shows the progress as a percentage bar in /components/progressdisplay jsx export default function progressdisplay({ progress }) { return ( \<div> \<div classname="w full bg gray 200 rounded"> \<div classname="bg blue 600 text xs font medium text blue 100 text center p 0 5 leading none rounded" style={{ width `${progress}%` }} \> {progress}% \</div> \</div> \</div> ); } 6\ pages and routing 6 1 list of tickets in /app/page js , display the list of tickets import { useeffect, usestate } from 'react'; import parse from ' /lib/parseclient'; import ticketcard from ' /components/ticketcard'; export default function home() { const \[tickets, settickets] = usestate(\[]); useeffect(() => { const fetchtickets = async () => { const query = new parse query('ticket'); const results = await query find(); settickets(results); }; fetchtickets(); }, \[]); return ( \<div> \<h1>tickets\</h1> {tickets map(ticket => ( \<ticketcard key={ticket id} ticket={ticket} /> ))} \</div> ); } 6 2 ticket detail and edit in /app/tickets/\[id]/page js import { useeffect, usestate } from 'react'; import { userouter } from 'next/router'; import parse from ' / / /lib/parseclient'; import ticketform from ' / / /components/ticketform'; import deleteblock from ' / / /components/deleteblock'; export default function ticketdetail() { const router = userouter(); const { id } = router query; const \[ticket, setticket] = usestate(null); useeffect(() => { if (!id) return; const fetchticket = async () => { const query = new parse query('ticket'); const result = await query get(id); setticket(result); }; fetchticket(); }, \[id]); const handledelete = () => { router push('/'); }; if (!ticket) return \<div>loading \</div>; return ( \<div> \<ticketform ticket={ticket} /> \<deleteblock ticketid={ticket id} ondelete={handledelete} /> \</div> ); } 7\ deploying to vercel 7 1 create a vercel account if you don’t already have a vercel account, head over to vercel com https //vercel com/ and create an account you can sign up with github, gitlab, or bitbucket vercel makes it easy to link your repository directly for deployments 7 2 push your code to github to deploy your app on vercel, you need to have your project hosted on a version control platform like github (or gitlab/bitbucket) if your project is not yet on github, follow these steps initialize git in your project directory add your project to github 7 3 install vercel cli (optional) if you prefer deploying directly from the command line, install the vercel cli globally alternatively, you can deploy via vercel's dashboard, which we’ll cover next 7 4 connect your github repository to vercel go to vercel https //vercel com/ click new project choose the git repository that contains your next js project configure your project vercel will automatically detect that it's a next js project and apply the correct build settings set the root directory to the project’s folder (if necessary) 7 5 set environment variables you’ll need to configure your back4app credentials and any other environment variables in vercel in vercel's project settings , go to the environment variables section add the following environment variables 7 6 set up parse configuration in env local (optional) if you use local environment variables during development, make sure to create a env local file in your root project directory with the following variables these environment variables will also be used by vercel once they are set in the vercel dashboard 7 7 configure build settings (optional) ensure that node js version and build command are correctly configured (vercel auto detects this) for next js apps, the default settings should be build command npm run build output directory next/ 7 8 deploy the project after you link your github repository, vercel will automatically trigger a build and deployment process you can view the status of your build in the vercel dashboard 7 9 check deployment logs if any issues arise during the deployment, you can inspect the deployment logs to debug them 7 10 access your deployed app once the deployment is successful, vercel will provide you with a unique url where your next js app is live you can visit the url to access your deployed ticketing app for example https //your app name vercel app/ 8\ ensuring smooth deployment back4app credentials double check that your back4app environment variables are correctly set in both env local (for local development) and the vercel dashboard (for production) cors (cross origin resource sharing) make sure that back4app allows your vercel url in its cors settings, which you can configure in the back4app dashboard under security test your api before deploying, test your back4app api interactions locally to ensure everything works smoothly 9\ conclusion with these steps, your next js ticketing app should now be deployed on vercel , using back4app for the backend this completes the full development cycle, from setting up back4app, creating the frontend in next js, to deploying the app live on vercel if you want to make updates, simply push changes to your github repository, and vercel will automatically trigger a new deployment