const apy = initApyhub(process.env.APY_TOKEN as string);
export { apy }; </pre><h2>How to use ApyHub API utilities</h2><h3>Fetching timezones</h3><p>Currently, our user interface (UI) has an empty dropdown menu for time zones. To avoid having to manually create the array ourselves, it would be beneficial to display all time zones in this menu. Fortunately, we can use the <a href="https://apyhub.com/utility/data-lists-timezone" rel="noopener noreferrer" target="_blank">data-lists-timezone</a> API for this purpose.</p><p><img src="https://assets.apyhub.com/images/with-next-js/5.png" alt="https://assets.apyhub.com/images/with-next-js/5.png"></p><p>ApyHub does not support client-side requests due to the security risk of exposing credentials to the client, which could lead to malicious actors making requests on your behalf. If you attempt to make a client-side API request, you will receive a CORS error. To ensure all API requests are handled from the server, Next.js serves as the bridge between the frontend and backend.</p><p>Inside the <code>/pages/index.tsx</code> file of your Next.js project, there is a <a href="https://nextjs.org/docs/basic-features/data-fetching/get-server-side-props" rel="noopener noreferrer" target="_blank">getServerSideProps</a> function. This is where server-side code is executed for Next.js projects.</p><p><img src="https://assets.apyhub.com/images/with-next-js/6.png" alt="https://assets.apyhub.com/images/with-next-js/6.png"></p><p>In here, we currently return an empty array for timezones. Let's change that by fetching an array of timezones from ApyHub. First, import and export the <code>data</code> object inside the <code>lib/apyhub.ts</code> file:</p><pre class="ql-syntax" spellcheck="false">import { initApyhub, data } from "apyhub";
const apy = initApyhub(process.env.APY_TOKEN as string);
export { apy, data }; </pre><p>Use <code>getServerSideProps</code> in the <code>/pages/index.tsx</code> file to fetch data.</p><pre class="ql-syntax" spellcheck="false">import { data } from "../lib/apyhub";
export const getServerSideProps = async () => { const { data: timezones } = await data.timezones(); return { props: { timezones, }, }; }; </pre><p>Reload the page to see all timezones in the dropdown menu - great!</p><p><img src="https://assets.apyhub.com/images/with-next-js/7.png" alt="https://assets.apyhub.com/images/with-next-js/7.png"></p><h3>Fetching iCal file</h3><p>Now that we can select a time zone from our drop-down, we have all the necessary components to generate a new iCal event. Next, we will create the API request to make this happen. To do this, we will use <a href="https://nextjs.org/docs/api-routes/introduction" rel="noopener noreferrer" target="_blank">Next.js API routes</a>.</p><p>Create a new API route. Inside the <code>/pages</code> folder, create a new folder called <code>api</code></p><p>Inside the <code>/pages/api</code> folder, create a new file called <code>ical.ts</code>.</p><p>We will use the <code>generate</code> object from the apyhub library to create a new iCal file.</p><p>Go to the <code>/lib/apyhub.ts</code> file and add the <code>generate</code> object, then export it:</p><pre class="ql-syntax" spellcheck="false">import { initApyhub, data, generate } from "apyhub";
const apy = initApyhub(process.env.APY_TOKEN as string);
export { apy, data, generate }; </pre><p>Inside the <code>/pages/api/ical.ts</code> file, create a new handler function. Pass the incoming request body data to the <code>generate.ical()</code> function:</p><pre class="ql-syntax" spellcheck="false">import { generate } from "../../lib/apyhub"; import { NextApiRequest, NextApiResponse } from "next";
const handler = async (req: NextApiRequest, res: NextApiResponse) => { const { summary, description, organizer_email, attendees_emails, location, timezone, start_time, end_time, meeting_date, recurring, recurrence, } = req.body; const url = await generate.ical({ summary, description, organizerEmail: organizer_email, attendeesEmails: attendees_emails, location, timeZone: timezone, startTime: start_time, endTime: end_time, meetingDate: meeting_date, recurring, recurrence, responseFormat: "url", }); return res.status(200).json(url); };
export default handler; </pre><p>We've finished! We can now generate an ical file with the given data and download it from our app. No more hassle!</p><p>To test it out, fill out the form in our app and click <code>Create Event</code>. The browser then makes a request to the <code>/api/ical.ts</code> API endpoint, which sends a request to ApyHub servers to create a new iCal file. We receive an URL pointing to this file, which we return to the browser. The file is then downloaded with <code>window.open(data, "_blank");</code>.</p><h2>Deployment</h2><p>Now that our app is complete, we can easily deploy it on Vercel. Follow <a href="https://nextjs.org/learn/basics/deploying-nextjs-app/deploy" rel="noopener noreferrer" target="_blank">these steps</a> and make sure to add the <code>APY_TOKEN</code> as an environment variable when deploying the application.</p><p><img src="https://assets.apyhub.com/images/with-next-js/8.png" alt="https://assets.apyhub.com/images/with-next-js/8.png"></p><h2>Bonus</h2><p>Currently, there is no way to validate if an organizer or attendee email provided on our app has a valid domain. To ensure accuracy, you can add the <a href="https://apyhub.com/utility/validator-dns-email" rel="noopener noreferrer" target="_blank">validator-dns-email</a> API to the <code>/api/ical.ts</code> API route before creating the iCal file. This will validate if the submitted email is valid.</p>
