Node.js + Express: How to return text files

Updated: December 30, 2023 By: Guest Contributor Post a comment

Introduction

In the contemporary world of web development, transferring various types of data between clients and servers is a fundamental operation. Among the plethora of content types, serving text files is a frequent requirement that Node.js developers encounter. This tutorial dives into the details of utilizing Node.js with the Express framework to efficiently and effectively return text files to clients. Whether you’re building APIs or server-rendered pages, knowing how to handle static text files is valuable knowledge.

The tutorial assumes familiarity with JavaScript (ECMAScript 2015 and newer) and at least a basic understanding of Node.js and its popular companion, Express.js.

Setting Up Your Environment

To get started, ensure that you have the recent LTS version of Node.js installed on your machine. Additionally, you need to set up a new Node.js project. Do this by initiating a new project in your desired directory:

mkdir my-textfile-project && cd my-textfile-project
npm init -y
npm install express --save

Create an ‘app.js’ file to hold your server code:

touch app.js

Basic Text File Serving

Serving files in Express is straightforward thanks to the built-in middleware ‘express.static’. For a simple plain text file, place it in a directory which can be considered public, and use the middleware to serve it:

import express from 'express';

const app = express();
const port = 3000;

app.use('/public', express.static('public'));

app.listen(port, () => {
   console.log(`Server is running on port ${port}`);
});

Now any file in the ‘public’ directory is accessible via the ‘/public’ URI preceded by the filename. However, serving all files from one folder might not be what you desire. We must explore another approach for this need.

Basic Route to Return a Specific Text File

The below example demonstrates setting up an Express route that specifically serves a single text file. Notice the use of ‘res.sendFile’, which sends the contents of a file:

import path from 'path';
import express from 'express';

const app = express();
const port = 3000;

app.get('/myfile', (req, res) => {
   res.sendFile(path.join(__dirname, '/public/myfile.txt'));
});

app.listen(port, () => {
   console.log(`Server is running on port ${port}`);
});

Handling File Not Found Errors

Sometimes the requested text file might not exist in the server directory. Rather than crashing the server or returning a status code that is uninformative, a proper error handling would result in a better user experience:

app.get('/myfile', async (req, res) => {
   try {
     await res.sendFile(path.join(__dirname, '/public/myfile.txt'));
   } catch (error) {
     if(error.code === 'ENOENT') {
       res.status(404).send('File not found');
     } else {
       res.status(500).send('An error occurred');
     }
   }
 });

Using Streams for Large Text Files

For significant performance increases when dealing with larger files, consider streaming the file contents to the client:

import fs from 'fs';

app.get('/myfile', (req, res) => {
  const readStream = fs.createReadStream(path.join(__dirname, '/public/myfile.txt'));
  readStream.pipe(res);
});

Piping a read stream to response object is a neat and efficient way of handling file transfers with node streams.

Setting Content Disposition for Downloads

If the text file should be prompted as a download rather than viewed in the browser, setting the ‘Content-Disposition’ header is vital:

app.get('/download-myfile', (req, res) => {
   const file = path.join(__dirname, '/public/myfile.txt');
   res.download(file);
 });

Final Words

This tutorial provided a glimpse into the basics and some advanced concepts related to serving text files using Node.js and Express. Remember, the examples showcased only scratch the surface. Specifying the correct MIME types, considering caching mechanisms, detailed error logging, and ensuring security by protecting against path traversal attacks are additional topics you will want to delve into as you grow in your Node.js journey.

Whether approached from a simplistic or an in-depth standpoint, the techniques and snippets provided herein will serve as a solid foundation for serving text files in your web applications.