Reader small image

You're reading from  Full Stack Web Development with Remix

Product typeBook
Published inNov 2023
Reading LevelIntermediate
PublisherPackt
ISBN-139781801075299
Edition1st Edition
Languages
Tools
Right arrow
Author (1)
Andre Landgraf
Andre Landgraf
author image
Andre Landgraf

Andre is a full stack developer from Germany. He graduated with an MS in Information Systems from the Technical University of Munich and was also awarded an MS in Computer Science from Sofia University in Palo Alto. Andre currently lives in Cupertino, California, and he works as a Software Engineer at LinkedIn. Andre loves learning, writing, and speaking about all things web. In his free time, he tutors aspiring developers and builds for the web.
Read more about Andre Landgraf

Right arrow

Working with File Uploads

Uploading files is something we do all the time on the web. The web provides built-in support for uploading files. However, uploading and processing files as part of a form submission still requires some additional considerations that we will cover in this chapter. This chapter is split into four sections:

  • Using multi-part form data in Remix
  • Processing files on the server
  • Authorizing access to assets with resource routes
  • Forwarding files to third-party services

In this chapter, we will iterate on BeeRich to support file uploads. First, we will update the creation and edit forms to allow adding and removing attachments. Next, we will refactor the action functions to process the attached files on the server. Further, we will investigate how to authorize access to uploaded files. Finally, we will learn about file size considerations and discuss different file storage solutions.

After reading this chapter, you will understand how...

Technical requirements

You can find the code for this chapter here: https://github.com/PacktPublishing/Full-Stack-Web-Development-with-Remix/blob/main/10-working-with-file-uploads/.

Before starting this chapter, follow the instructions in the README.md file in this chapter’s folder on GitHub to clean up the experiments from Chapter 9, Assets and Metadata Handling.

Using multi-part form data in Remix

By default, form data is encoded using the application/x-www-form-urlencoded encoding type. URL-encoded form data appends the form data as key-value pairs to the request URL as search parameters. To attach files to HTML forms, we need to change the form’s encoding type. Appending form data to the URL is not the right approach when transferring binary data such as files. In this section, you will learn how to use multi-part encoding to support file uploads.

There are three different encoding types for HTML form elements:

  • application/x-www-form-urlencoded
  • multipart/form-data
  • text/plain

text/plain is not what we are looking for. Plaintext encoding is not used for client-server communication as it submits the data in a human-readable format. Instead, we want to use multipart/form-data encoding, which places the form data into the request body, making it possible to include and stream binary files.

Let’s update...

Processing files on the server

There are several important considerations when handling file uploads on the server, most importantly the file size. In this section, we will learn how to process files in Remix’s action functions. We will start with a naïve implementation before refactoring the code and taking more concerns into account.

Loading files into memory

Let’s get started by implementing some utilities for working with files:

  1. Create a new app/modules/attachments.server.ts file.
  2. Add the following code to attachments.server.ts:
    import fs from 'fs';import path from 'path';export async function writeFile(file: File) {  const localPath = path.join(process.cwd(), 'public', file.name);  const arrayBufferView = new Uint8Array(await file.arrayBuffer());  fs.writeFileSync(localPath, arrayBufferView);}

    The added writeFile function accepts a file and writes it to the public folder. Note that this...

Forwarding files to third-party services

So far, we are hosting our user files on the server’s filesystem. This is sufficient for the educative scope of BeeRich. However, when working with user files, we should also consider hosting them on a dedicated file storage service. This section quickly outlines what else we need to consider when working with user files.

Hosting user files directly on a web server may not be sufficient for most use cases. Hosting files locally may be hard to scale and requires you to secure sensitive user files and backups on your systems. Additionally, reading and writing to disk might create a lot of overhead for the web server that can be avoided by delegating the reads and writes to a third-party service.

Most popular third-party storage services offer APIs to stream files. This allows us to receive the file upload as a stream of data so that we can forward the stream to a third-party service. After the upload is completed, the storage API...

Summary

In this chapter, you learned how to add files to HTML forms and how to handle file uploads in Remix.

HTML forms support different encoding types. Multipart form encoding adds the form data to the response body. This is required when appending binary data, such as files. On the server, we can then stream in the response body and handle the uploaded files in chunks.

By reading this chapter, you now understand that Remix provides a set of file upload utilities for handling file uploads. Remix utilities help us avoid filenaming collisions and allow us to configure file size limits and file streaming. We can further compose several file upload handlers together and implement custom wrappers by implementing the UploadHandler type.

Next, you learned how to restrict access to a resource route by authenticating user sessions and ensuring authorized database queries that query for a unique combination of entity id and user id. We must not place user files in the public folder...

Further reading

You can learn more about the HTML form element’s enctype property via MDN Web Docs: https://developer.mozilla.org/en-US/docs/Web/API/HTMLFormElement/enctype.

You can find additional information about HTTP POST requests via MDN Web Docs: https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST.

Review this example implementation from Remix’s example repository for uploading files to Cloudinary: https://github.com/remix-run/examples/tree/main/file-and-cloudinary-upload.

You can learn more about Remix’s file upload helpers by reading the Remix documentation:

lock icon
The rest of the chapter is locked
You have been reading a chapter from
Full Stack Web Development with Remix
Published in: Nov 2023Publisher: PacktISBN-13: 9781801075299
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
undefined
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at €14.99/month. Cancel anytime

Author (1)

author image
Andre Landgraf

Andre is a full stack developer from Germany. He graduated with an MS in Information Systems from the Technical University of Munich and was also awarded an MS in Computer Science from Sofia University in Palo Alto. Andre currently lives in Cupertino, California, and he works as a Software Engineer at LinkedIn. Andre loves learning, writing, and speaking about all things web. In his free time, he tutors aspiring developers and builds for the web.
Read more about Andre Landgraf