{"id":31394,"date":"2023-10-09T07:00:00","date_gmt":"2023-10-09T14:00:00","guid":{"rendered":"https:\/\/cloudinary.com\/blog\/?p=31394"},"modified":"2025-11-26T22:05:19","modified_gmt":"2025-11-27T06:05:19","slug":"building-portfolio-xata-cloudinary-next-js","status":"publish","type":"post","link":"https:\/\/cloudinary.com\/blog\/building-portfolio-xata-cloudinary-next-js","title":{"rendered":"Building a Portfolio With Xata, Cloudinary, and Next.js"},"content":{"rendered":"\n<p>Telling stories is one of the most effective ways to sell ourselves. In recent times, visual content has dominated the web, making storytelling with pictures an even more captivating technique.<\/p>\n\n\n\n<p>This blog post aims to build a portfolio that provides an overview of storing, sending, and retrieving data and using these data to promote ourselves.<\/p>\n\n\n\n<p>At the end of the post, your portfolio should look like <a href=\"https:\/\/vimeo.com\/768020342\/17f93ef041\" target=\"_blank\" rel=\"noreferrer noopener\">this<\/a>.<\/p>\n\n\n\n<p>The live demo of this application is available&nbsp;<a href=\"https:\/\/cloudinary-xata-portfolio.netlify.app\/\" target=\"_blank\" rel=\"noreferrer noopener\">here<\/a>. Here\u2019s the&nbsp;<a href=\"https:\/\/github.com\/Anita9771\/xata-clone\" target=\"_blank\" rel=\"noreferrer noopener\">source code<\/a>&nbsp;for the project.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Prerequisites<\/strong><\/h2>\n\n\n\n<p>To complete this project, you&#8217;ll need to have:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Knowledge of React and&nbsp;<a href=\"https:\/\/nextjs.org\/?utm_source=hackmamba&amp;utm_campaign=hackmamba-hackathon&amp;utm_medium=hackmamba-blog\">Next.js<\/a>.<\/li>\n\n\n\n<li>Node and its package manager,&nbsp;<code>npm<\/code>. Run the command&nbsp;<code>node -v &amp;&amp; npm -v<\/code>&nbsp;to verify that you have them installed or install them from&nbsp;<a href=\"https:\/\/nodejs.org\/en\/\">here<\/a>.<\/li>\n\n\n\n<li><a href=\"https:\/\/code.visualstudio.com\/\" target=\"_blank\" rel=\"noreferrer noopener\">Code Editor<\/a>.<\/li>\n\n\n\n<li><a href=\"https:\/\/www.typescriptlang.org\/\" target=\"_blank\" rel=\"noreferrer noopener\">TypeScript<\/a><\/li>\n\n\n\n<li>A&nbsp;<a href=\"https:\/\/xata.io\/\">Xata<\/a>&nbsp;account. Create one&nbsp;<a href=\"https:\/\/app.xata.io\/signin\" target=\"_blank\" rel=\"noreferrer noopener\">here<\/a>.<\/li>\n\n\n\n<li>A&nbsp;<a href=\"https:\/\/cloudinary.com\/\">Cloudinary<\/a>&nbsp;account. Create one&nbsp;<a href=\"https:\/\/cloudinary.com\/\" target=\"_blank\" rel=\"noreferrer noopener\">here<\/a>.<\/li>\n<\/ul>\n\n\n<div class='c-callout  c-callout--inline-title c-callout--note'><strong class='c-callout__title'>Note:<\/strong> <p>To get you started, the prerequisites are attached with links to guide you. You can also catch up with crash courses.<\/p>\n<\/div>\n\n\n<h3 class=\"wp-block-heading\"><a href=\"https:\/\/dev.to\/hackmamba\/building-a-portfolio-with-xata-cloudinary-and-nextjs-4bn2#what-is-xata\"><\/a>What is Xata?<\/h3>\n\n\n\n<p><a href=\"https:\/\/xata.io\/?utm_source=hackmamba&amp;utm_campaign=hackmamba-hackathon&amp;utm_medium=hackmamba-blog\" target=\"_blank\" rel=\"noreferrer noopener\">Xata<\/a>&nbsp;is a branchable, serverless database that offers a web UI making working with data seamless, an indefinitely scalable data API, and more.<\/p>\n\n\n\n<p><a href=\"https:\/\/xata.io\/?utm_source=hackmamba&amp;utm_campaign=hackmamba-hackathon&amp;utm_medium=hackmamba-blog\" target=\"_blank\" rel=\"noreferrer noopener\">Xata<\/a>&nbsp;allows you to store, retrieve, update, delete, search through data, and more.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><a href=\"https:\/\/dev.to\/hackmamba\/building-a-portfolio-with-xata-cloudinary-and-nextjs-4bn2#why-cloudinary\"><\/a>Why Cloudinary?<\/h3>\n\n\n\n<p><a href=\"https:\/\/cloudinary.com\/?utm_source=hackmamba&amp;utm_medium=hackmamba-blog&amp;utm_campaign=hackmamba-hackathon\" target=\"_blank\" rel=\"noreferrer noopener\">Cloudinary<\/a>&nbsp;provides extensive video management and a cloud-based image platform while optimally creating, managing, and delivering digital experiences. With&nbsp;<a href=\"https:\/\/cloudinary.com\/?utm_source=hackmamba&amp;utm_medium=hackmamba-blog&amp;utm_campaign=hackmamba-hackathon\" target=\"_blank\" rel=\"noreferrer noopener\">Cloudinary<\/a>, you can store, upload, transform, download, and embed images.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><a href=\"https:\/\/dev.to\/hackmamba\/building-a-portfolio-with-xata-cloudinary-and-nextjs-4bn2#getting-started\"><\/a>Getting Started<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\"><a href=\"https:\/\/dev.to\/hackmamba\/building-a-portfolio-with-xata-cloudinary-and-nextjs-4bn2#setting-up-a-cloudinary-account\"><\/a>Setting Up a Cloudinary Account<\/h3>\n\n\n\n<p>Head to&nbsp;<a href=\"https:\/\/cloudinary.com\/?utm_source=hackmamba&amp;utm_medium=hackmamba-blog&amp;utm_campaign=hackmamba-hackathon\" target=\"_blank\" rel=\"noreferrer noopener\">Cloudinary<\/a> and log in to your account or create an account&nbsp;<a href=\"https:\/\/cloudinary.com\/?utm_source=hackmamba&amp;utm_medium=hackmamba-blog&amp;utm_campaign=hackmamba-hackathon\" target=\"_blank\" rel=\"noreferrer noopener\">here<\/a>.<\/p>\n\n\n\n<p>After successfully creating an account,&nbsp;<a href=\"https:\/\/cloudinary.com\/?utm_source=hackmamba&amp;utm_medium=hackmamba-blog&amp;utm_campaign=hackmamba-hackathon\" target=\"_blank\" rel=\"noreferrer noopener\">Cloudinary<\/a>&nbsp;will then redirect you to your account&#8217;s dashboard page, where you can see account details that will be useful later on, including your:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Cloud name<\/li>\n\n\n\n<li>API Key<\/li>\n\n\n\n<li>API Secret<\/li>\n<\/ul>\n\n\n<div class='c-callout  c-callout--inline-title c-callout--note'><strong class='c-callout__title'>Note:<\/strong> <p>Do not share these details with anyone.<\/p>\n<\/div>\n\n\n<p>Next, go to <strong>Media Library<\/strong> to create a folder to house your images.<\/p>\n\n\n\n<p>Upload images to the created folder with a simple drag and drop. Next, copy the uploaded image links. You\u2019ll use this when building your application.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><a href=\"https:\/\/dev.to\/hackmamba\/building-a-portfolio-with-xata-cloudinary-and-nextjs-4bn2#setting-up-your-xata-account\"><\/a>Setting Up Your Xata Account<\/h3>\n\n\n\n<p>Visit\u00a0Xata\u00a0to log in to your account or create an account\u00a0<a href=\"https:\/\/app.xata.io\/signin\" target=\"_blank\" rel=\"noreferrer noopener\">here<\/a>.<\/p>\n\n\n\n<p>After creating an account,\u00a0Xata\u00a0will redirect you to create a workspace for your project. Next, you\u2019ll create a database to house your project data. You&#8217;ll then create tables serving as the database component holding your data. Finally, you\u2019ll add data to the table you created in the step above.<\/p>\n\n\n<div class='c-callout  c-callout--inline-title c-callout--note'><strong class='c-callout__title'>Note:<\/strong> <p>The image column content is the URLs of images copied from Cloudinary.<\/p>\n<\/div>\n\n\n<h2 class=\"wp-block-heading\"><a href=\"https:\/\/dev.to\/hackmamba\/building-a-portfolio-with-xata-cloudinary-and-nextjs-4bn2#project-setup-and-installation\"><\/a>Project Setup and Installation<\/h2>\n\n\n\n<p>You\u2019ll be bootstrapping&nbsp;<code>with-xata<\/code>&nbsp;template using the&nbsp;<code>create-next-app<\/code>&nbsp;command.<\/p>\n\n\n\n<p>Open your Node.js terminal after you&#8217;ve navigated to the directory you want the project on:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\">npx create-next-app --example <span class=\"hljs-keyword\">with<\/span>-xata <span class=\"hljs-keyword\">with<\/span>-xata-app<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>You&#8217;ll get some prompts, including a prompt to create a dummy new table (<code>nextjs_with_xata_example<\/code>). If you already have an existing database, you can ignore. Otherwise, accept to get some content displayed on&nbsp;<code>npm run start<\/code>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Install the Xata CLI<\/h3>\n\n\n\n<p>In the terminal, run&nbsp;<code>npm install @xata.io\/cli -g<\/code>&nbsp;to install&nbsp;<a href=\"https:\/\/xata.io\/?utm_source=hackmamba&amp;utm_campaign=hackmamba-hackathon&amp;utm_medium=hackmamba-blog\" target=\"_blank\" rel=\"noreferrer noopener\">Xata<\/a>&nbsp;for global use.<\/p>\n\n\n\n<p>Then link an existing database by initializing with&nbsp;<code>xata init --db=[databaseUrl]<\/code>. Run&nbsp;<code>npm run start:xata<\/code>&nbsp;to get Xata started.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Build the Homepage Component<\/h3>\n\n\n\n<p>Let\u2019s add our logo to the&nbsp;<code>_app.tsx<\/code>&nbsp;just above the&nbsp;<code>Component<\/code>&nbsp;declaration, as shown below.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml shcb-wrap-lines\">\/\/ _app.tsx\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">h2<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">'logo'<\/span>&gt;<\/span>MODE-EL<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">h2<\/span>&gt;<\/span>\n      <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Component<\/span> {<span class=\"hljs-attr\">...pageProps<\/span>} \/&gt;<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>In the&nbsp;<code>index.tsx<\/code>&nbsp;file, replace the default syntax with the code snippet below.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php shcb-wrap-lines\">    import type { InferGetServerSidePropsType } from <span class=\"hljs-string\">\"next\"<\/span>;\n    import { XataClient, getXataClient } from <span class=\"hljs-string\">\"..\/utils\/xata.codegen\"<\/span>;\n\n    export <span class=\"hljs-keyword\">default<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">IndexPage<\/span><span class=\"hljs-params\">({\n    }: InferGetServerSidePropsType&lt;typeof getServerSideProps&gt;)<\/span> <\/span>{\n      <span class=\"hljs-comment\">\/\/ Some UI rendering<\/span>\n      <span class=\"hljs-keyword\">return<\/span> (\n        &lt;div className=<span class=\"hljs-string\">\"homepage\"<\/span>&gt;\n           {<span class=\"hljs-comment\">\/* Take the content here out to input your own content *\/<\/span>}\n        {<span class=\"hljs-comment\">\/* Hero Section *\/<\/span>}\n\n        {<span class=\"hljs-comment\">\/* About section *\/<\/span>}\n\n        {<span class=\"hljs-comment\">\/* More about section *\/<\/span>}\n\n        {<span class=\"hljs-comment\">\/* Testimonial section *\/<\/span>}\n\n        {<span class=\"hljs-comment\">\/* Contact section *\/<\/span>}\n\n        {<span class=\"hljs-comment\">\/* Scroll to top *\/<\/span>}\n\n        {<span class=\"hljs-comment\">\/* Footer section *\/<\/span>}\n        &lt;\/div&gt;\n      );\n    }\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>This displays the content of different sections, as seen above.<\/p>\n\n\n\n<p>Let\u2019s get into defining what each section does. In the&nbsp;<code>Hero section<\/code>, display the images of links from&nbsp;<a href=\"https:\/\/cloudinary.com\/?utm_source=hackmamba&amp;utm_campaign=hackmamba-hackathon&amp;utm_medium=hackmamba-blog\" target=\"_blank\" rel=\"noreferrer noopener\">Cloudinary<\/a>&nbsp;as the first section to be seen when a viewer visits your portfolio.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml shcb-wrap-lines\">    \/\/ Hero section\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"homepage\"<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">'top-images'<\/span>&gt;<\/span>\n           <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">img<\/span> <span class=\"hljs-attr\">src<\/span>=<span class=\"hljs-string\">\"image link from cloudinary\"<\/span> <span class=\"hljs-attr\">alt<\/span>=<span class=\"hljs-string\">\" \"<\/span> \/&gt;<\/span>\n           <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">img<\/span> <span class=\"hljs-attr\">src<\/span>=<span class=\"hljs-string\">\"image link from cloudinary\"<\/span> <span class=\"hljs-attr\">alt<\/span>=<span class=\"hljs-string\">\" \"<\/span> \/&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n\n         <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">'top-content'<\/span>&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">h1<\/span>&gt;<\/span>think <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">span<\/span>&gt;<\/span>you've seen<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">span<\/span>&gt;<\/span> magic?<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">h1<\/span>&gt;<\/span>\n             <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">'top-content-btn'<\/span>&gt;<\/span>\n               <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">button<\/span> <span class=\"hljs-attr\">id<\/span>=<span class=\"hljs-string\">\"contactBtn\"<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">'left-button'<\/span>&gt;<\/span> CONTACT US <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">button<\/span>&gt;<\/span>\n               <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">button<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">'right-button'<\/span>&gt;<\/span>GALLERY<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">button<\/span>&gt;<\/span>\n          <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n     <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Next, the&nbsp;<code>About section<\/code>&nbsp;shows some information about you, such as text, call-to-action, etc.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml shcb-wrap-lines\">    \/\/ About section\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">'dancing-lady'<\/span>&gt;<\/span>\n       <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">img<\/span> <span class=\"hljs-attr\">src<\/span>=<span class=\"hljs-string\">\"image link from cloudinary\"<\/span> <span class=\"hljs-attr\">alt<\/span>=<span class=\"hljs-string\">\" \"<\/span>\/&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">'cta-one'<\/span>&gt;<\/span>\n       <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">h2<\/span>&gt;<\/span># Photography Agency<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">h2<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">p<\/span>&gt;<\/span>\n            We are the problem solvers that will help you convey your message in\n            pixels. We communicate creatively both online and offline and always\n            putting a smile on your face through satisfaction.\n        <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">p<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Also,&nbsp;<code>More about section<\/code>&nbsp;gives viewers more context about the portfolio.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml shcb-wrap-lines\">    \/\/ More about section\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">'woman-in-glasses'<\/span>&gt;<\/span>\n       <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">img<\/span> <span class=\"hljs-attr\">src<\/span>=<span class=\"hljs-string\">\"image link from cloudinary\"<\/span> <span class=\"hljs-attr\">alt<\/span>=<span class=\"hljs-string\">\" \"<\/span> \/&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">'cta-two'<\/span>&gt;<\/span>\n       <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">h2<\/span>&gt;<\/span>Want To Be Discovered?<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">h2<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">p<\/span>&gt;<\/span>\n           We are the problem solvers that will help you convey your message in\n            pixels. We communicate creatively both online and offline and always\n            putting a smile on your face through satisfaction.\n        <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">p<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">'guy-in-glasses'<\/span>&gt;<\/span>\n       <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">img<\/span> <span class=\"hljs-attr\">src<\/span>=<span class=\"hljs-string\">\"image link from cloudinary\"<\/span> <span class=\"hljs-attr\">alt<\/span>=<span class=\"hljs-string\">\" \"<\/span> \/&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>In the&nbsp;<code>Testimonial section<\/code>, we&#8217;ll get data in the form of testimonials from&nbsp;<a href=\"https:\/\/xata.io\/\" target=\"_blank\" rel=\"noreferrer noopener\">Xata<\/a>&nbsp;to display in your project.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-7\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml shcb-wrap-lines\">    \/\/ Testimonial section\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">'testimonials'<\/span>&gt;<\/span>\n       <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">'testimonials-head'<\/span>&gt;<\/span>\n         <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">h2<\/span>&gt;<\/span>TESTIMONIALS<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">h2<\/span>&gt;<\/span>\n       <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n       <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">'testimonial'<\/span>&gt;<\/span>\n        {\/* Fetched data from xata to be displayed *\/}\n    <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-7\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Next is the&nbsp;<code>Contact section<\/code>, where you\u2019ll display a form to get viewers&#8217; data and send it to the database.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-8\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml shcb-wrap-lines\">    \/\/ Contact section\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">id<\/span>=<span class=\"hljs-string\">\"contact\"<\/span>&gt;<\/span>\n       {\/* contact form*\/}\n\n    {\/* Scroll to top *\/}\n      <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">i<\/span> \n          <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\" \"<\/span>&gt;<\/span>\n          {\/* arrow up icon *\/}\n      <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">i<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-8\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>The last section in the&nbsp;<code>index.tsx<\/code>&nbsp;is the&nbsp;<code>Footer section<\/code>, where you\u2019ll place the content of your footer.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-9\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml shcb-wrap-lines\">    \/\/ Footer section\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">footer<\/span>&gt;<\/span>\n       <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">p<\/span>&gt;<\/span>\n         MODE-EL <span class=\"hljs-symbol\">&amp;#169;<\/span> 2022\n       <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">p<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">footer<\/span>&gt;<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-9\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Let&#8217;s make our contact form displayed on the index page and serve as our data collection point to be sent to Xata.<br>In the root folder, we&#8217;ll create a&nbsp;<code>components<\/code>&nbsp;folder, then create our&nbsp;<code>ContactForm.tsx<\/code><\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-10\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\">    <span class=\"hljs-comment\">\/\/ components\/ContactForm.tsx<\/span>\n\n    <span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">const<\/span> ContactForm = <span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> {\n      <span class=\"hljs-keyword\">return<\/span> (\n        <span class=\"hljs-comment\">\/\/ form to submit details<\/span>\n        <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"\"<\/span>&gt;<\/span>\n          <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">form<\/span>&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">p<\/span>&gt;<\/span>Need us!<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">p<\/span>&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">input<\/span>\n              <span class=\"hljs-attr\">type<\/span>=<span class=\"hljs-string\">\"text\"<\/span>\n              <span class=\"hljs-attr\">name<\/span>=<span class=\"hljs-string\">\"name\"<\/span>\n              <span class=\"hljs-attr\">value<\/span>=<span class=\"hljs-string\">{}<\/span>\n              <span class=\"hljs-attr\">required<\/span>\n              <span class=\"hljs-attr\">placeholder<\/span>=<span class=\"hljs-string\">\"Name\"<\/span>\n            \/&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">input<\/span>\n              <span class=\"hljs-attr\">type<\/span>=<span class=\"hljs-string\">\"email\"<\/span>\n              <span class=\"hljs-attr\">name<\/span>=<span class=\"hljs-string\">\"email\"<\/span>\n              <span class=\"hljs-attr\">value<\/span>=<span class=\"hljs-string\">{}<\/span>\n              <span class=\"hljs-attr\">required<\/span>\n              <span class=\"hljs-attr\">placeholder<\/span>=<span class=\"hljs-string\">\"Email\"<\/span>\n            \/&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">input<\/span>\n              <span class=\"hljs-attr\">type<\/span>=<span class=\"hljs-string\">\"text\"<\/span>\n              <span class=\"hljs-attr\">name<\/span>=<span class=\"hljs-string\">\"message\"<\/span>\n              <span class=\"hljs-attr\">value<\/span>=<span class=\"hljs-string\">{}<\/span>\n              <span class=\"hljs-attr\">required<\/span>\n              <span class=\"hljs-attr\">placeholder<\/span>=<span class=\"hljs-string\">\"Message\"<\/span>\n            \/&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">button<\/span>&gt;<\/span>SEND<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">button<\/span>&gt;<\/span>\n          <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">form<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span><\/span>\n      );\n    };\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-10\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>To be able to send data to the&nbsp;<a href=\"https:\/\/xata.io\/\" target=\"_blank\" rel=\"noreferrer noopener\">Xata<\/a>&nbsp;table created, you need to send the value of the inputs as responses.<\/p>\n\n\n\n<p>In the&nbsp;<code>api<\/code>&nbsp;folder located in the&nbsp;<code>pages<\/code>&nbsp;folder, create a&nbsp;<code>submit-response.ts<\/code>&nbsp;file where you&#8217;ll call the API.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-11\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\">    <span class=\"hljs-comment\">\/\/ pages\/submit-response.ts<\/span>\n\n    <span class=\"hljs-keyword\">import<\/span> { NextApiHandler } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"next\"<\/span>;\n    <span class=\"hljs-keyword\">import<\/span> { XataClient, getXataClient } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"..\/..\/utils\/xata.codegen\"<\/span>;\n    <span class=\"hljs-keyword\">import<\/span> dotenv <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"dotenv\"<\/span>;\n    dotenv.config();\n\n    <span class=\"hljs-comment\">\/\/ connecting to xata<\/span>\n    <span class=\"hljs-keyword\">const<\/span> handler: NextApiHandler = <span class=\"hljs-keyword\">async<\/span> (req, res) =&gt; {\n      <span class=\"hljs-keyword\">const<\/span> xata = <span class=\"hljs-keyword\">new<\/span> XataClient({ <span class=\"hljs-attr\">apiKey<\/span>: process.env.{insert your API key} });\n      <span class=\"hljs-keyword\">const<\/span> { name, email, message } = req.body;\n      <span class=\"hljs-keyword\">await<\/span> xata.db.contacts.create({\n        name,\n        email,\n        message,\n      });\n      res.end();\n    };\n\n    <span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> handler;\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-11\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>In the&nbsp;<code>ContactForm.tsx<\/code>, implement your API route,&nbsp;<code>submit-response.ts<\/code>.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-12\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\">    <span class=\"hljs-comment\">\/\/ components\/ContactForm.tsx<\/span>\n\n    <span class=\"hljs-keyword\">import<\/span> { useState } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"react\"<\/span>;\n\n    <span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">const<\/span> TestForm = <span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> {\n      <span class=\"hljs-keyword\">const<\/span> &#91;name, setName] = useState(<span class=\"hljs-string\">\"\"<\/span>);\n      <span class=\"hljs-keyword\">const<\/span> &#91;message, setMessage] = useState(<span class=\"hljs-string\">\"\"<\/span>);\n      <span class=\"hljs-keyword\">const<\/span> &#91;email, setEmail] = useState(<span class=\"hljs-string\">\"\"<\/span>);\n\n      <span class=\"hljs-comment\">\/\/ fetch xata API<\/span>\n      <span class=\"hljs-keyword\">const<\/span> send = <span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> {\n        fetch(<span class=\"hljs-string\">\"api\/submit-response\"<\/span>, {\n          <span class=\"hljs-attr\">method<\/span>: <span class=\"hljs-string\">\"POST\"<\/span>,\n          <span class=\"hljs-attr\">headers<\/span>: {\n            <span class=\"hljs-attr\">Authorization<\/span>: <span class=\"hljs-string\">`Basic <span class=\"hljs-subst\">${process.env.{insert your API key}<\/span>}`<\/span>,\n            <span class=\"hljs-string\">\"Content-Type\"<\/span>: <span class=\"hljs-string\">\"application\/json\"<\/span>,\n          },\n          <span class=\"hljs-attr\">body<\/span>: <span class=\"hljs-built_in\">JSON<\/span>.stringify({\n            <span class=\"hljs-attr\">email<\/span>: email,\n            <span class=\"hljs-attr\">message<\/span>:message,\n            <span class=\"hljs-attr\">name<\/span>: name,\n          }),\n        }).then(<span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> <span class=\"hljs-built_in\">window<\/span>.location.reload());\n      };\n\n      <span class=\"hljs-keyword\">return<\/span> (\n        <span class=\"hljs-comment\">\/\/ form to submit details<\/span>\n    ...........................................................\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-12\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Then, import the&nbsp;<code>ContactForm.tsx<\/code>&nbsp;in your&nbsp;<code>index.tsx<\/code>.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-13\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml shcb-wrap-lines\">    \/\/ Contact section\n\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">id<\/span>=<span class=\"hljs-string\">\"contact\"<\/span>&gt;<\/span>\n    {\/* Import at the top *\/}\n      <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">ContactForm<\/span> \/&gt;<\/span>\n      <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">i<\/span> \n          <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\" \"<\/span>&gt;<\/span>\n          {\/* arrow up icon *\/}\n      <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">i<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-13\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>At this point, your&nbsp;<code>ContactForm.tsx<\/code>&nbsp;on the&nbsp;<code>index.tsx<\/code>&nbsp;should look like this:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/res.cloudinary.com\/practicaldev\/image\/fetch\/s--gR3UDuz_--\/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880\/https:\/\/paper-attachments.dropboxusercontent.com\/s_12E5EF309E3ED73109B68483C792B48A7576FB98AA056F771D1B4203BF354320_1668595777376_Screenshot%2B62.png\"><img decoding=\"async\" src=\"https:\/\/cloudinary-marketing-res.cloudinary.com\/image\/upload\/v1764223477\/blog-Building_a_Portfolio_With_Xata_Cloudinary_and_Next.js-1.png\" alt=\"Contact form\"\/><\/a><\/figure>\n\n\n\n<p>This contact form will send data to the&nbsp;<a href=\"https:\/\/xata.io\/\" target=\"_blank\" rel=\"noreferrer noopener\">Xata<\/a>&nbsp;database. Try filling, submitting, and checking the data table in&nbsp;<a href=\"https:\/\/xata.io\/\" target=\"_blank\" rel=\"noreferrer noopener\">Xata<\/a>, and you&#8217;ll see the table populated with what you just submitted.<\/p>\n\n\n\n<p>Now, you\u2019ll get the data you created on your&nbsp;<a href=\"https:\/\/xata.io\/\" target=\"_blank\" rel=\"noreferrer noopener\">Xata<\/a>&nbsp;database when you created the table, as this is what you&#8217;ll display as your testimonial section.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-14\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\">    <span class=\"hljs-comment\">\/\/ index.tsx<\/span>\n\n    <span class=\"hljs-keyword\">import<\/span> type { InferGetServerSidePropsType } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"next\"<\/span>;\n    <span class=\"hljs-keyword\">import<\/span> { XataClient, getXataClient } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"..\/utils\/xata.codegen\"<\/span>;\n    <span class=\"hljs-keyword\">import<\/span> { ContactForm } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"..\/components\/ContactForm\"<\/span>;\n    <span class=\"hljs-keyword\">import<\/span> dotenv <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"dotenv\"<\/span>;\n    dotenv.config();\n\n    <span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">IndexPage<\/span>(<span class=\"hljs-params\">{\n      <span class=\"hljs-regexp\">\/\/<\/span> adding the props in this case links\n      links,\n    }: InferGetServerSidePropsType&lt;typeof getServerSideProps&gt;<\/span>) <\/span>{\n\n      <span class=\"hljs-comment\">\/\/ Some UI rendering<\/span>\n      <span class=\"hljs-keyword\">return<\/span> (\n       <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"homepage\"<\/span>&gt;<\/span>\n         {\/* different sections of the page*\/}\n      <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span><\/span>\n      );\n    }\n\n    <span class=\"hljs-comment\">\/\/ fetching db from xata<\/span>\n    <span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">const<\/span> getServerSideProps = <span class=\"hljs-keyword\">async<\/span> () =&gt; {\n    <span class=\"hljs-keyword\">const<\/span> xata = <span class=\"hljs-keyword\">new<\/span> XataClient({ <span class=\"hljs-attr\">apiKey<\/span>: process.env.{insert your API key} });\n    <span class=\"hljs-keyword\">const<\/span> links = <span class=\"hljs-keyword\">await<\/span> xata.db.clients.getAll();\n      <span class=\"hljs-keyword\">return<\/span> {\n        <span class=\"hljs-attr\">props<\/span>: {\n          links,\n        },\n      };\n    };\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-14\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Then, loop through the data from Xata\u2019s database on the testimonial page.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-15\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml shcb-wrap-lines\">          {\/* testimonial section*\/}\n     <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">'testimonials'<\/span>&gt;<\/span>\n       <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">'testimonials-head'<\/span>&gt;<\/span>\n         <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">h2<\/span>&gt;<\/span>TESTIMONIALS<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">h2<\/span>&gt;<\/span>\n       <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n       <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">'testimonial'<\/span>&gt;<\/span>\n           {links.map((link) =&gt; {\n                return (\n                  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">section<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">'testimonial-single'<\/span> <span class=\"hljs-attr\">key<\/span>=<span class=\"hljs-string\">{link.id}<\/span>&gt;<\/span>\n                    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">img<\/span> <span class=\"hljs-attr\">src<\/span>=<span class=\"hljs-string\">{link.image}<\/span> <span class=\"hljs-attr\">alt<\/span>=<span class=\"hljs-string\">\"testimonial image\"<\/span> \/&gt;<\/span>\n                    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">p<\/span>&gt;<\/span><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">b<\/span>&gt;<\/span>{link.name}<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">b<\/span>&gt;<\/span><span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">p<\/span>&gt;<\/span>\n                    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">p<\/span>&gt;<\/span>{link.occupation}<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">p<\/span>&gt;<\/span>\n                    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">p<\/span>&gt;<\/span>{link.description}<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">p<\/span>&gt;<\/span>\n                  <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">section<\/span>&gt;<\/span>\n                );\n              })}\n        <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-15\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>If implemented correctly, you should have this result:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/res.cloudinary.com\/practicaldev\/image\/fetch\/s--2SA3eqiN--\/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880\/https:\/\/paper-attachments.dropboxusercontent.com\/s_12E5EF309E3ED73109B68483C792B48A7576FB98AA056F771D1B4203BF354320_1668595580864_Screenshot%2B61.png\"><img decoding=\"async\" src=\"https:\/\/cloudinary-marketing-res.cloudinary.com\/image\/upload\/v1764223479\/blog-Building_a_Portfolio_With_Xata_Cloudinary_and_Next.js-2.jpg\" alt=\"testimonial section\"\/><\/a><\/figure>\n\n\n\n<p>In the&nbsp;<code>index.tsx<\/code>&nbsp;page, you&#8217;ll be writing functions for the scroll behavior.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-16\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\">      <span class=\"hljs-comment\">\/\/ index.tsx<\/span>\n    <span class=\"hljs-comment\">\/\/ scroll to top<\/span>\n      <span class=\"hljs-keyword\">const<\/span> onBtnClick = <span class=\"hljs-function\">(<span class=\"hljs-params\">e<\/span>) =&gt;<\/span> {\n        e.preventDefault();\n        setTimeout(<span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> {\n          <span class=\"hljs-built_in\">window<\/span>.scrollTo({\n            <span class=\"hljs-attr\">top<\/span>: <span class=\"hljs-built_in\">document<\/span>.getElementById(<span class=\"hljs-string\">\"contact\"<\/span>).offsetTop - <span class=\"hljs-number\">60<\/span>,\n            <span class=\"hljs-attr\">behavior<\/span>: <span class=\"hljs-string\">\"smooth\"<\/span>,\n          });\n        }, <span class=\"hljs-number\">50<\/span>);\n      };\n\n      <span class=\"hljs-comment\">\/\/ scroll to top<\/span>\n      <span class=\"hljs-keyword\">const<\/span> onIconClick = <span class=\"hljs-function\">(<span class=\"hljs-params\">e<\/span>) =&gt;<\/span> {\n        e.preventDefault();\n        setTimeout(<span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> {\n          <span class=\"hljs-built_in\">window<\/span>.scrollTo({\n            <span class=\"hljs-attr\">top<\/span>: <span class=\"hljs-built_in\">document<\/span>.getElementById(<span class=\"hljs-string\">\"contactBtn\"<\/span>).offsetTop - <span class=\"hljs-number\">60<\/span>,\n            <span class=\"hljs-attr\">behavior<\/span>: <span class=\"hljs-string\">\"smooth\"<\/span>,\n          });\n        }, <span class=\"hljs-number\">50<\/span>);\n      };\n\n     <span class=\"hljs-keyword\">return<\/span> (\n       <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"homepage\"<\/span>&gt;<\/span>\n         {\/* different sections of the page*\/}\n      <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span><\/span>\n      );\n    }\n\n    .................................................................\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-16\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Then, add the functions to click events in the&nbsp;<code>hero section<\/code>&nbsp;and&nbsp;<code>contact section<\/code>, as shown below.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-17\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml shcb-wrap-lines\">    \/\/ hero section\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">'top-content'<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">h1<\/span>&gt;<\/span>think <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">span<\/span>&gt;<\/span>you've seen<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">span<\/span>&gt;<\/span> magic?<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">h1<\/span>&gt;<\/span>\n         <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">'top-content-btn'<\/span>&gt;<\/span>\n           <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">button<\/span> <span class=\"hljs-attr\">id<\/span>=<span class=\"hljs-string\">\"contactBtn\"<\/span> <span class=\"hljs-attr\">onClick<\/span>=<span class=\"hljs-string\">{onBtnClick}<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">'left-button'<\/span>&gt;<\/span> \n              CONTACT US \n            <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">button<\/span>&gt;<\/span>\n           <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">button<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">'right-button'<\/span>&gt;<\/span>GALLERY<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">button<\/span>&gt;<\/span>\n         <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n     <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-17\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-18\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml shcb-wrap-lines\">    \/\/ contact section\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">id<\/span>=<span class=\"hljs-string\">\"contact\"<\/span>&gt;<\/span>\n      <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">ContactForm<\/span> \/&gt;<\/span>\n      <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">i<\/span>\n          <span class=\"hljs-attr\">onClick<\/span>=<span class=\"hljs-string\">{onIconClick}<\/span>\n          <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\" \"<\/span>&gt;<\/span>\n          {\/* arrow up icon *\/}\n      <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">i<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-18\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>In the&nbsp;<code>hero section<\/code>&nbsp;of the&nbsp;<code>index.tsx<\/code>, link the gallery button to a gallery page that you\u2019ll create shortly.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-19\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml shcb-wrap-lines\">    \/\/ hero section\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">'top-content'<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">h1<\/span>&gt;<\/span>think <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">span<\/span>&gt;<\/span>you've seen<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">span<\/span>&gt;<\/span> magic?<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">h1<\/span>&gt;<\/span>\n         <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">'top-content-btn'<\/span>&gt;<\/span>\n           <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">button<\/span> <span class=\"hljs-attr\">id<\/span>=<span class=\"hljs-string\">\"contactBtn\"<\/span> <span class=\"hljs-attr\">onClick<\/span>=<span class=\"hljs-string\">{onBtnClick}<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">'left-button'<\/span>&gt;<\/span> \n              CONTACT US \n            <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">button<\/span>&gt;<\/span>\n\n             {\/* import Link at the top *\/}\n           <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Link<\/span> <span class=\"hljs-attr\">href<\/span>=<span class=\"hljs-string\">\"\/gallery\"<\/span>&gt;<\/span>\n                <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">button<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">'right-button'<\/span>&gt;<\/span>GALLERY<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">button<\/span>&gt;<\/span>\n              <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">Link<\/span>&gt;<\/span>\n         <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n     <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-19\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>In the&nbsp;<code>pages<\/code>&nbsp;folder, create a new file&nbsp;<code>gallery.tsx<\/code>. This page is where the&nbsp;<a href=\"https:\/\/cloudinary.com\/\" target=\"_blank\" rel=\"noreferrer noopener\">Cloudinary<\/a>&nbsp;API and personal details collected will be used to interact with the images uploaded to&nbsp;<a href=\"https:\/\/cloudinary.com\/\" target=\"_blank\" rel=\"noreferrer noopener\">Cloudinary<\/a>.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-20\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\">    <span class=\"hljs-comment\">\/\/ gallery.tsx<\/span>\n    <span class=\"hljs-keyword\">import<\/span> type { InferGetServerSidePropsType } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"next\"<\/span>;\n    <span class=\"hljs-keyword\">import<\/span> Link <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"next\/link\"<\/span>;\n\n    <span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">gallery<\/span>(<span class=\"hljs-params\">{\n      images,\n    }: InferGetServerSidePropsType&lt;typeof getServerSideProps&gt;<\/span>) <\/span>{\n\n      <span class=\"hljs-comment\">\/\/ Some UI rendering<\/span>\n      <span class=\"hljs-keyword\">return<\/span> (\n        <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"gallery\"<\/span>&gt;<\/span>     \n        <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span><\/span>\n      );\n    }\n\n    <span class=\"hljs-comment\">\/\/ Calling cloudinary API<\/span>\n    <span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">const<\/span> getServerSideProps = <span class=\"hljs-keyword\">async<\/span> () =&gt; {\n      <span class=\"hljs-keyword\">const<\/span> results = <span class=\"hljs-keyword\">await<\/span> fetch(\n        <span class=\"hljs-string\">`https:\/\/api.cloudinary.com\/v1_1\/<span class=\"hljs-subst\">${process.env.{your cloudinary cloud name}<\/span>}\/resources\/image`<\/span>,\n        {\n          <span class=\"hljs-attr\">headers<\/span>: {\n            <span class=\"hljs-attr\">Authorization<\/span>: <span class=\"hljs-string\">`Basic <span class=\"hljs-subst\">${Buffer.<span class=\"hljs-keyword\">from<\/span>(\n              process.env.{your cloudinary API key}<\/span> +\n                \":\" +\n                process.env.{your cloudinary API secret}\n            ).toString(\"base64\")}`<\/span>,\n          },\n        }\n      ).then(<span class=\"hljs-function\">(<span class=\"hljs-params\">res<\/span>) =&gt;<\/span> res.json());\n\n      <span class=\"hljs-keyword\">const<\/span> { resources } = results;\n\n      <span class=\"hljs-keyword\">const<\/span> images = resources?.map(<span class=\"hljs-function\">(<span class=\"hljs-params\">resource<\/span>) =&gt;<\/span> {\n        <span class=\"hljs-keyword\">const<\/span> { width, height } = resource;\n        <span class=\"hljs-keyword\">return<\/span> {\n          <span class=\"hljs-attr\">id<\/span>: resource.asset_id,\n          <span class=\"hljs-attr\">title<\/span>: resource.public_id,\n          <span class=\"hljs-attr\">image<\/span>: resource.secure_url,\n          width,\n          height,\n        };\n      });\n      <span class=\"hljs-keyword\">return<\/span> {\n        <span class=\"hljs-attr\">props<\/span>: {\n          images,\n        },\n      };\n    };\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-20\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>To display the images, map through the images gotten through the API.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-21\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml shcb-wrap-lines\">     \/\/ gallery.tsx \n    \/\/ Some UI rendering\n      return (\n    div className=\"gallery\"&gt;\n      {\/* Looping through cloudinary images *\/}\n      <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"images\"<\/span>&gt;<\/span>\n        {images?.map((image) =&gt; {\n          return (\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">key<\/span>=<span class=\"hljs-string\">{image.id}<\/span>&gt;<\/span>\n              <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">img<\/span> <span class=\"hljs-attr\">src<\/span>=<span class=\"hljs-string\">{image.image}<\/span> <span class=\"hljs-attr\">alt<\/span>=<span class=\"hljs-string\">{image.title}<\/span> \/&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n          );\n        })}\n      <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n\n      <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">nav<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Link<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"link\"<\/span> <span class=\"hljs-attr\">href<\/span>=<span class=\"hljs-string\">\"\/\"<\/span>&gt;<\/span>\n          HOME\n        <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">Link<\/span>&gt;<\/span>\n      <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">nav<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n    );\n    }\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-21\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>This will render a collection of images from Cloudinary uploads, as shown below.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/res.cloudinary.com\/practicaldev\/image\/fetch\/s--lGynQ-sh--\/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880\/https:\/\/paper-attachments.dropboxusercontent.com\/s_12E5EF309E3ED73109B68483C792B48A7576FB98AA056F771D1B4203BF354320_1668595497913_Screenshot%2B65.png\"><img decoding=\"async\" src=\"https:\/\/cloudinary-marketing-res.cloudinary.com\/image\/upload\/v1764223482\/blog-Building_a_Portfolio_With_Xata_Cloudinary_and_Next.js-3.jpg\" alt=\"Gallery page\"\/><\/a><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\"><a href=\"https:\/\/dev.to\/hackmamba\/building-a-portfolio-with-xata-cloudinary-and-nextjs-4bn2#conclusion\"><\/a>Conclusion<\/h3>\n\n\n\n<p>You&#8217;ve successfully built a photography portfolio using Cloudinary, Next.js, and Xata, where creators can display their work, show comments from previous clients and get feedback or messages from viewers.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Telling stories is one of the most effective ways to sell ourselves. In recent times, visual content has dominated the web, making storytelling with pictures an even more captivating technique. This blog post aims to build a portfolio that provides an overview of storing, sending, and retrieving data and using these data to promote ourselves. [&hellip;]<\/p>\n","protected":false},"author":87,"featured_media":31398,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_cloudinary_featured_overwrite":false,"footnotes":""},"categories":[1],"tags":[212],"class_list":["post-31394","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized","tag-next-js"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v25.6 (Yoast SEO v26.9) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Building a Portfolio With Xata, Cloudinary, and Next.js<\/title>\n<meta name=\"description\" content=\"Telling stories is one of the most effective ways to sell ourselves. In recent times, visual content has dominated the web, making storytelling with\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/cloudinary.com\/blog\/building-portfolio-xata-cloudinary-next-js\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Building a Portfolio With Xata, Cloudinary, and Next.js\" \/>\n<meta property=\"og:description\" content=\"Telling stories is one of the most effective ways to sell ourselves. In recent times, visual content has dominated the web, making storytelling with\" \/>\n<meta property=\"og:url\" content=\"https:\/\/cloudinary.com\/blog\/building-portfolio-xata-cloudinary-next-js\" \/>\n<meta property=\"og:site_name\" content=\"Cloudinary Blog\" \/>\n<meta property=\"article:published_time\" content=\"2023-10-09T14:00:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-11-27T06:05:19+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1696620194\/Blog-Hackmamba_Building_a_Portfolio\/Blog-Hackmamba_Building_a_Portfolio.jpg?_i=AA\" \/>\n\t<meta property=\"og:image:width\" content=\"2000\" \/>\n\t<meta property=\"og:image:height\" content=\"1100\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"melindapham\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"NewsArticle\",\"@id\":\"https:\/\/cloudinary.com\/blog\/building-portfolio-xata-cloudinary-next-js#article\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/building-portfolio-xata-cloudinary-next-js\"},\"author\":{\"name\":\"melindapham\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#\/schema\/person\/0d5ad601e4c3b5be89245dfb14be42d9\"},\"headline\":\"Building a Portfolio With Xata, Cloudinary, and Next.js\",\"datePublished\":\"2023-10-09T14:00:00+00:00\",\"dateModified\":\"2025-11-27T06:05:19+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/building-portfolio-xata-cloudinary-next-js\"},\"wordCount\":1009,\"publisher\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/building-portfolio-xata-cloudinary-next-js#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1696620194\/Blog-Hackmamba_Building_a_Portfolio\/Blog-Hackmamba_Building_a_Portfolio.jpg?_i=AA\",\"keywords\":[\"Next.js\"],\"inLanguage\":\"en-US\",\"copyrightYear\":\"2023\",\"copyrightHolder\":{\"@id\":\"https:\/\/cloudinary.com\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/cloudinary.com\/blog\/building-portfolio-xata-cloudinary-next-js\",\"url\":\"https:\/\/cloudinary.com\/blog\/building-portfolio-xata-cloudinary-next-js\",\"name\":\"Building a Portfolio With Xata, Cloudinary, and Next.js\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/building-portfolio-xata-cloudinary-next-js#primaryimage\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/building-portfolio-xata-cloudinary-next-js#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1696620194\/Blog-Hackmamba_Building_a_Portfolio\/Blog-Hackmamba_Building_a_Portfolio.jpg?_i=AA\",\"datePublished\":\"2023-10-09T14:00:00+00:00\",\"dateModified\":\"2025-11-27T06:05:19+00:00\",\"description\":\"Telling stories is one of the most effective ways to sell ourselves. In recent times, visual content has dominated the web, making storytelling with\",\"breadcrumb\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/building-portfolio-xata-cloudinary-next-js#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/cloudinary.com\/blog\/building-portfolio-xata-cloudinary-next-js\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/cloudinary.com\/blog\/building-portfolio-xata-cloudinary-next-js#primaryimage\",\"url\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1696620194\/Blog-Hackmamba_Building_a_Portfolio\/Blog-Hackmamba_Building_a_Portfolio.jpg?_i=AA\",\"contentUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1696620194\/Blog-Hackmamba_Building_a_Portfolio\/Blog-Hackmamba_Building_a_Portfolio.jpg?_i=AA\",\"width\":2000,\"height\":1100},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/cloudinary.com\/blog\/building-portfolio-xata-cloudinary-next-js#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/cloudinary.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Building a Portfolio With Xata, Cloudinary, and Next.js\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#website\",\"url\":\"https:\/\/cloudinary.com\/blog\/\",\"name\":\"Cloudinary Blog\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/cloudinary.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\",\"name\":\"Cloudinary Blog\",\"url\":\"https:\/\/cloudinary.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA\",\"contentUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA\",\"width\":312,\"height\":60,\"caption\":\"Cloudinary Blog\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#\/schema\/person\/0d5ad601e4c3b5be89245dfb14be42d9\",\"name\":\"melindapham\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/e6f989fa97fe94be61596259d8629c3df65aec4c7da5c0000f90d810f313d4f4?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/e6f989fa97fe94be61596259d8629c3df65aec4c7da5c0000f90d810f313d4f4?s=96&d=mm&r=g\",\"caption\":\"melindapham\"}}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Building a Portfolio With Xata, Cloudinary, and Next.js","description":"Telling stories is one of the most effective ways to sell ourselves. In recent times, visual content has dominated the web, making storytelling with","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/cloudinary.com\/blog\/building-portfolio-xata-cloudinary-next-js","og_locale":"en_US","og_type":"article","og_title":"Building a Portfolio With Xata, Cloudinary, and Next.js","og_description":"Telling stories is one of the most effective ways to sell ourselves. In recent times, visual content has dominated the web, making storytelling with","og_url":"https:\/\/cloudinary.com\/blog\/building-portfolio-xata-cloudinary-next-js","og_site_name":"Cloudinary Blog","article_published_time":"2023-10-09T14:00:00+00:00","article_modified_time":"2025-11-27T06:05:19+00:00","og_image":[{"width":2000,"height":1100,"url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1696620194\/Blog-Hackmamba_Building_a_Portfolio\/Blog-Hackmamba_Building_a_Portfolio.jpg?_i=AA","type":"image\/jpeg"}],"author":"melindapham","twitter_card":"summary_large_image","schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"NewsArticle","@id":"https:\/\/cloudinary.com\/blog\/building-portfolio-xata-cloudinary-next-js#article","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/building-portfolio-xata-cloudinary-next-js"},"author":{"name":"melindapham","@id":"https:\/\/cloudinary.com\/blog\/#\/schema\/person\/0d5ad601e4c3b5be89245dfb14be42d9"},"headline":"Building a Portfolio With Xata, Cloudinary, and Next.js","datePublished":"2023-10-09T14:00:00+00:00","dateModified":"2025-11-27T06:05:19+00:00","mainEntityOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/building-portfolio-xata-cloudinary-next-js"},"wordCount":1009,"publisher":{"@id":"https:\/\/cloudinary.com\/blog\/#organization"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/building-portfolio-xata-cloudinary-next-js#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1696620194\/Blog-Hackmamba_Building_a_Portfolio\/Blog-Hackmamba_Building_a_Portfolio.jpg?_i=AA","keywords":["Next.js"],"inLanguage":"en-US","copyrightYear":"2023","copyrightHolder":{"@id":"https:\/\/cloudinary.com\/#organization"}},{"@type":"WebPage","@id":"https:\/\/cloudinary.com\/blog\/building-portfolio-xata-cloudinary-next-js","url":"https:\/\/cloudinary.com\/blog\/building-portfolio-xata-cloudinary-next-js","name":"Building a Portfolio With Xata, Cloudinary, and Next.js","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/building-portfolio-xata-cloudinary-next-js#primaryimage"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/building-portfolio-xata-cloudinary-next-js#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1696620194\/Blog-Hackmamba_Building_a_Portfolio\/Blog-Hackmamba_Building_a_Portfolio.jpg?_i=AA","datePublished":"2023-10-09T14:00:00+00:00","dateModified":"2025-11-27T06:05:19+00:00","description":"Telling stories is one of the most effective ways to sell ourselves. In recent times, visual content has dominated the web, making storytelling with","breadcrumb":{"@id":"https:\/\/cloudinary.com\/blog\/building-portfolio-xata-cloudinary-next-js#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/cloudinary.com\/blog\/building-portfolio-xata-cloudinary-next-js"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/cloudinary.com\/blog\/building-portfolio-xata-cloudinary-next-js#primaryimage","url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1696620194\/Blog-Hackmamba_Building_a_Portfolio\/Blog-Hackmamba_Building_a_Portfolio.jpg?_i=AA","contentUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1696620194\/Blog-Hackmamba_Building_a_Portfolio\/Blog-Hackmamba_Building_a_Portfolio.jpg?_i=AA","width":2000,"height":1100},{"@type":"BreadcrumbList","@id":"https:\/\/cloudinary.com\/blog\/building-portfolio-xata-cloudinary-next-js#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/cloudinary.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Building a Portfolio With Xata, Cloudinary, and Next.js"}]},{"@type":"WebSite","@id":"https:\/\/cloudinary.com\/blog\/#website","url":"https:\/\/cloudinary.com\/blog\/","name":"Cloudinary Blog","description":"","publisher":{"@id":"https:\/\/cloudinary.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/cloudinary.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/cloudinary.com\/blog\/#organization","name":"Cloudinary Blog","url":"https:\/\/cloudinary.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA","contentUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA","width":312,"height":60,"caption":"Cloudinary Blog"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/cloudinary.com\/blog\/#\/schema\/person\/0d5ad601e4c3b5be89245dfb14be42d9","name":"melindapham","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/cloudinary.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/e6f989fa97fe94be61596259d8629c3df65aec4c7da5c0000f90d810f313d4f4?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/e6f989fa97fe94be61596259d8629c3df65aec4c7da5c0000f90d810f313d4f4?s=96&d=mm&r=g","caption":"melindapham"}}]}},"jetpack_featured_media_url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1696620194\/Blog-Hackmamba_Building_a_Portfolio\/Blog-Hackmamba_Building_a_Portfolio.jpg?_i=AA","_links":{"self":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/31394","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/users\/87"}],"replies":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/comments?post=31394"}],"version-history":[{"count":6,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/31394\/revisions"}],"predecessor-version":[{"id":39471,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/31394\/revisions\/39471"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media\/31398"}],"wp:attachment":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media?parent=31394"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/categories?post=31394"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/tags?post=31394"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}