Skip to content

Commit

Permalink
docs: fix typos in article
Browse files Browse the repository at this point in the history
  • Loading branch information
atinux committed Aug 22, 2024
1 parent 8af0745 commit 803591d
Showing 1 changed file with 22 additions and 20 deletions.
42 changes: 22 additions & 20 deletions docs/content/5.blog/2.drawing-app-with-nuxt-and-cloudflare-r2.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ category: Tutorial

## Introduction

I won't go into each details of the code, but I'll try to explain the main concepts and how to build a drawing app with Nuxt and Cloudflare R2.
I won't go into each detail of the code, but I'll try to explain the main concepts and how to build a drawing app with Nuxt and Cloudflare R2.

Atidraw is a web application that lets you to create and share your drawings with the world. Harnessing the power of OAuth for user authentication and Cloudflare R2 to store and list the drawings.
Atidraw is a web application that lets you create and share your drawings with the world. Our app uses OAuth for user authentication and Cloudflare R2 to store and list drawings.

The application is running with server-side rendering on the edge using Cloudflare Pages on the Workers free plan.
The application runs with server-side rendering on the edge using Cloudflare Pages on the Workers free plan.

::video{poster="https://res.cloudinary.com/nuxt/video/upload/v1723210615/nuxthub/344159247-85f79def-f633-40b7-97c2-3a8579e65af1_xyrfin.jpg" controls class="lg:w-2/3 h-auto border dark:border-gray-800 rounded"}
:source{src="https://res.cloudinary.com/nuxt/video/upload/v1723210615/nuxthub/344159247-85f79def-f633-40b7-97c2-3a8579e65af1_xyrfin.webm" type="video/webm"}
Expand All @@ -29,15 +29,15 @@ The application is running with server-side rendering on the edge using Cloudfla
::

::note{to="https://draw.nuxt.dev" icon="i-ph-rocket-launch-duotone" color="blue" target="_blank"}
The demo is available on **draw.nuxt.dev**.
The demo is available at **draw.nuxt.dev**.
::
::callout{to="https://github.com/atinux/atidraw" icon="i-simple-icons-github" color="gray" target="_blank"}
The source code of the app is available on **github.com/atinux/atidraw**.
The source code of the app is available at **github.com/atinux/atidraw**.
::

## Project Dependencies

Our Nuxt application is using the following dependencies:
Our Nuxt application uses the following dependencies:

- [`nuxt-auth-utils`](https://github.com/atinux/nuxt-auth-utils) for user authentication
- [`signature_pad`](https://github.com/szimek/signature_pad) for the drawing canvas
Expand All @@ -61,16 +61,16 @@ export default defineNuxtConfig({
```

::note
The `blob` option will use Cloudflare platform proxy in development and automatically create a Cloudflare R2 bucket for your project when you deploy it. It also provide helpers to upload and list files.
The `blob` option will use Cloudflare platform proxy in development and automatically create a Cloudflare R2 bucket for your project when you deploy it. It also provides helpers to upload and list files.
::

::tip
The project is also using the `future.compatibilityVersion: 4` option to use the [new directory structure](https://nuxt.com/docs/getting-started/upgrade#new-directory-structure).
The project is also using the `future.compatibilityVersion: 4` option to leverage the [new directory structure](https://nuxt.com/docs/getting-started/upgrade#new-directory-structure).
::

## User Authentication

For user authentication, we'll use [`nuxt-auth-utils`](https://github.com/atinux/nuxt-auth-utils), it providers helpers to authenticate users with OAuth providers and storing the user session in encrypted cookies.
For user authentication, we'll use [`nuxt-auth-utils`](https://github.com/atinux/nuxt-auth-utils). It provides functions to authenticate users with OAuth providers and stores the user session in encrypted cookies.

First, we need to set up a session secret (used to encrypt & decrypt the session cookie) and our OAuth application credentials in the `.env` file:

Expand Down Expand Up @@ -101,14 +101,14 @@ export default oauthGitHubEventHandler({
```

::tip
The `.get.ts` suffix is indicating that only GET requests will be handled by this route.
The `.get.ts` suffix indicates that only GET requests will be handled by this route.
::

When the user hits `/auth/github`:
1. `oauthGitHubEventHandler` redirects the user to the GitHub OAuth page
2. The user is redirected back to **/auth/github**
2. The user is then redirected back to **/auth/github**
3. `onSuccess()` is called and the user session is set in a cookie
4. The user is redirected to **/draw**
4. The user is finally redirected to **/draw**

In [`app/pages/draw.vue`](https://github.com/atinux/atidraw/blob/main/app/pages/draw.vue), we can leverage [`useUserSession()`](https://github.com/atinux/nuxt-auth-utils?tab=readme-ov-file#vue-composable) to know if the user is authenticated or not.

Expand Down Expand Up @@ -251,18 +251,18 @@ export default eventHandler(async (event) => {
```

::tip
The `requireUserSession()` helper is provided by [`nuxt-auth-utils`](https://github.com/atinux/nuxt-auth-utils) and will throw a `401` error if the user is not authenticated.
The `requireUserSession()` function is provided by [`nuxt-auth-utils`](https://github.com/atinux/nuxt-auth-utils) and will throw a `401` error if the user is not authenticated.
::

As you can see, we don't need to have a database as we store the user metadata in the Cloudflare R2 bucket custom metadata.
As you can see, we don't need a database as we store the user metadata in the Cloudflare R2 bucket custom metadata.

::note
Learn more about the [`hubBlob()`](/docs/storage/blob) server helper to work with the Cloudflare R2 bucket.
Learn more about the [`hubBlob()`](/docs/storage/blob) server function to work with the Cloudflare R2 bucket.
::

## List Drawings

It's time to list our users drawings, first, we need to create a new API route in `server/api/drawings.get.ts`:
It's time to list our user drawings! First, however, we need to create a new API route in `server/api/drawings.get.ts`:

```ts [server/api/drawings.get.ts]
export default eventHandler(async (event) => {
Expand Down Expand Up @@ -293,15 +293,17 @@ const { data } = await useFetch('/api/drawings')
</template>
```

::tip{icon="i-ph-rocket-launch"}
That's it! We have a minimal and fully functional drawing application.
::

## Drawings Order

You may have noticed that the last drawing is displayed last, this is because Cloudflare R2 is using alphabetical order to list the files and we use the timestamp (using `Date.now()`) as the file name. Also, R2 doesn't support listing files with a custom order.

Even though it's easy to add a Cloudflare D1 database with [`hubDatabase()`](/docs/storage/database), I wanted to keep this example as simple as possible.

Instead, I had the idea to use the timestamp in 2050 minus the timestamp of the drawing to get a descending order. Yeah, it's a bit hacky but it works, until 2050, it's still a long time 😄.
Instead, I had the idea to use the timestamp in 2050 minus the timestamp of the drawing to get a descending order. It's not perfect but it works, until 2050, it's still a long time 😄.

Let's update our **/api/upload** route to update the filename:

Expand Down Expand Up @@ -465,13 +467,13 @@ Or go to https://admin.hub.nuxt.com and select your project.

Congratulations! You've now built a fully functional drawing application using Nuxt and Cloudflare R2 for storage. Users can create drawings, save them to the cloud, and access them from anywhere.

Next, we are going to leverage Cloudflare AI to generate the alt text for the user drawings (accessibility & SEO) as well as generating an alternative drawing using AI.
Next, we are going to leverage Cloudflare AI to generate the alternative text for the user drawings (accessibility & SEO) as well as generating an alternative drawing using AI.

Feel free to expand on this foundation and add your own unique features to make Atidraw yours!

::callout{to="https://github.com/atinux/atidraw" icon="i-simple-icons-github" color="gray" target="_blank"}
The source code of the app is available on **github.com/atinux/atidraw**.
The source code of the app is available at **github.com/atinux/atidraw**.
::
::note{to="https://draw.nuxt.dev" icon="i-ph-rocket-launch-duotone" target="_blank"}
The demo is available on **draw.nuxt.dev**.
The demo is available at **draw.nuxt.dev**.
::

0 comments on commit 803591d

Please sign in to comment.