Netlify Dynamic Site Challenge: Make your own thank you postcards
Tags: netlifychallenge, devchallenge, webdev, javascript
Published: 2024-05-12 04:53:49

*This is a submission for the [Netlify Dynamic Site Challenge](https://dev.to/challenges/netlify): Visual Feast.*


## What I Built
I built a site where you can **customize, download and print your own minimalist postcard**. You can download and print your designs at home - as individual images or a generated PDF.

You may be thinking you can do the same thing on the Walgreens or Costco websites - and they will print _and_ ship the cards to you. Yes, you can. But, personally, I've never liked those over-colored, whimsical and cheesy designs.

TL;DR - the longer backstory. Every year, I design our family's holiday cards and a few moms always ask what site I used to do it - to which I thought, I should start a custom holiday card business. Then, I forgot about this idea until I saw this Netflify challenge and immediately got to work on a few templates and an mvp. I realize I could've just made & sold some  Canva templates - but unfortunately, I'm a software engineer and I just had to build a whole platform from scratch.

**The Stack:** NextJS + React + Tailwind, Supabase database + storage + auth, Resend email smtp, Netlify hosting


## Demo

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xk6e2nk6g05ac456jxeh.png)
**https://postcards.makenakong.com**

Feel free to [make an account](https://postcards.makenakong.com/signup) and create your own postcard - i'd love to get feedback!

Otherwise, here are some screenshotted walkthroughs:
### creating a postcard
**step 1: choose a template**
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/05xv03irrh302t5uiaq0.png)
**step 2: customize your card**
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4hi9b0z490nlc4j929mr.png)
**step 3: export & print your card**
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4m91mumc6lcz9ewsup3r.png)
### my postcards
view & reprint your postcards
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bw89jcjxtnrqt4wreyc5.png)
### postcard gallery
view everyone's postcards!
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h0t5ohz0pl4dwfdw8yae.png)


Future Features: User account management, naming/updating/deleting postcards, more templates and customization options, a landing page, hook up to a printing api idk


## Platform Primitives
**Using Netlify Image CDN on-demand image transformations**

1. All postcard images (in /gallery, /my-postcards, /postcard/:id) are **converted to .avif format at half their original pixel dimensions and 75% quality via a Netlify Image CDN transformation**.

2. Postcard images can be exported in it's original .webp format and original dimensions or **exported in a .jpeg format and original pixel dimensions via a Netlify Image CDN transformation**.

```
namespace ImageUtils {
  export namespace Netlify {
    const BASE_NETLIFY_URL = `${process.env.NEXT_PUBLIC_SITE_URL}/.netlify/images/`;

    export interface INetlifyImageParamProps {
      url: string;
      w?: number;
      h?: number;
      fit?: string; //"object" | "contain" | "fill";
      position?: string; //"center" | "top" | "bottom" | "left" | "right";
      format?: string; //"avif" | "jpg" | "png" | "webp" | "gif" | "blurhash";
      quality?: number;
    }

    export function getUrl(data: INetlifyImageParamProps) {
      const params = Object.entries(data)
        .map((entry) => `${entry[0]}=${entry[1]}`)
        .join("&");
      return `${BASE_NETLIFY_URL}?${params}`;
    }
  }
}
```

Thanks for reading! Happy postcard making!