When using MERN Stack (with Typescript) on DigitalOcean, encountering an issue where HTML files are displayed instead of JS and

Upon checking the console, I encountered this

https://i.sstatic.net/PWoT5.jpg

The app has been developed using Ubuntu and Nginx so far with no firewall configuration yet in place. This is my first time deploying a MERN stack and utilizing DigitalOcean.

Here are the steps I am following to get the app up and running:

  1. Starting by running npm run build on the server to compile tsx to js.

  2. Then proceeding to run npm run build on the client side.

  3. Moving the client's build folder to the server's build folder while renaming it as 'static'.

  4. In the server folder, executing pm2 start build/index.js to point to build/static/index.html.

Upon visiting the droplet IP address, the following image shows the result.

https://i.sstatic.net/1IQ0Y.jpg

The js/main.js file remains unchanged.

Below is the content of my index.ts file.

import express from 'express'
import userRoutes from './routes/user-routes'
import membershipRoutes from './routes/membership-routes'
import memberPlanRoutes from './routes/plan-routes'
import passwordRoutes from './routes/password-routes'
import memberExtendRoutes from './routes/extend-routes'
import bodyParser from 'body-parser'
import mongoose from 'mongoose'
import dotenv from 'dotenv'
import cors from 'cors'
import path from 'path'

const app = express()

dotenv.config()

app.use(express.urlencoded({ limit: '50mb', extended: true }))
app.use(express.static('static'))
app.use(cors())
app.enable('trust proxy')

app.use((req, res, next) => {
  res.setHeader('Access-Control-Allow-Origin', '*')
  res.setHeader(
    'Access-Control-Allow-Headers',
    'Origin, X-Requested-With, Content-Type, Accept, Authorization'
  )
  res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PATCH, DELETE')
  next()
})

app.get('*', (req, res) => {
  res.sendFile(path.join(__dirname, 'static/index.html'))
})


app.use('/api/membership/webhook', bodyParser.raw({ type: '*/*' }))
app.use(express.json({ limit: '50mb' }))
app.use('/api/user', userRoutes)
app.use('/api/membership', membershipRoutes)
app.use('/api/plan', memberPlanRoutes)
app.use('/api/password', passwordRoutes)
app.use('/api/extend', memberExtendRoutes)

mongoose.connect(process.env.MONGODB_URL as string).then(() => {
  console.log('connected to mongodb')
})


app.listen(8080, () => {
  console.log(`Your server is ready on port 8080!`)
})

I have attempted changing app.get('*') to ('/') along with other variations, but it resulted in the same outcome or no static folder at all.

I also came across the following comment, but I am unsure how to implement it.

https://i.sstatic.net/4bN9Y.jpg

Your assistance would be highly appreciated, thank you!

Answer №1

Thanks to a helpful user on DigitalOcean, this code was generously provided and has successfully resolved the issue!

app.use(express.static(path.join(__dirname, 'assets')));
app.get('*', (req, res) => {
  res.sendFile(path.resolve(__dirname, 'assets', 'main.html'));
});

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Troubleshooting: Issue with reloading in MERN setup on Heroku

I successfully deployed my MERN stack application on Heroku using the following code: import express from "express"; import path from "path"; const app = express(); const port = process.env.PORT || 5000; app.get("/health-check&qu ...

Updating the React State is dependent on the presence of a useless state variable in addition to the necessary state variable being set

In my current setup, the state is structured as follows: const [items, setItems] = useState([] as CartItemType[]); const [id, setId] = useState<number | undefined>(); The id variable seems unnecessary in this context and serves no purpose in my appl ...

Converting Angular 5 select option values to strings is a must

I have set up a basic select connected to a variable like this: <select id="client" name="client" [(ngModel)]="order.clientId"> <option *ngFor="let client of clients" [value]="client.id"> {{ client.name }} </option> </ ...

Implementing Adsterra in your next.js or react.js project: A step-by-step guide

Currently, I am working on integrating the Adsterra Banner 300x50 into a ts/js reactjs + nextjs project. The provided script code from Adsterra is as follows: <script type="text/javascript"> atOptions = { 'key' : 'XXXXXX&a ...

Include the providers after declaring the AppModule

When it comes to Angular 2+, providers are typically registered in the following manner: // Using the @NgModule decorator and its metadata @NgModule({ declarations: [...], imports: [...], providers: [<PROVIDERS GO HERE>], bootstrap: [...] }) ...

Issue: The error message "TypeError: React.createContext is not a function" occurs when using Next.js 13 alongside Formik with TypeScript

I'm currently working on creating a form using Formik in NextJs 13 (Typescript). However, the form I designed isn't functioning properly. To troubleshoot, I added code snippets from Formik's examples as shown below. Unfortunately, both my fo ...

Saving JSON data retrieved from the server into an array in Angular 2

Using a nodejs server to retrieve data from an SQL database has been challenging. I attempted to store the data in taches, which is an array of Tache : getTaches(): Observable<Tache[]> { return this.http.get(this.tachesUrl) .map(response => ...

Can we verify if strings can serve as valid property names for interfaces?

Let's consider an interface presented below: interface User { id: string; name: string; age: number; } We also have a method defined as follows: function getUserValues(properties:string[]):void { Ajax.fetch("user", properties).then( ...

What is the process for obtaining the complete URL using the getDownloadURL() function along with a token?

An error occurred due to an unresolved FirebaseStorageError: "storage/object-not-found". The message indicates that the object 'k91a73uzb99' does not exist in Firebase Storage. This type of error is categorized under FirebaseError with a code of ...

I am having trouble locating my TypeScript package that was downloaded from the NPM registry. It seems to be showing as "module not found"

Having some challenges with packaging my TypeScript project that is available on the npm registry. As a newcomer to module packaging for others, it's possible I've made an error somewhere. The following sections in the package.json appear to be ...

Executing a function within the same file is referred to as intra-file testing

I have two functions where one calls the other and the other returns a value, but I am struggling to get the test to work effectively. When using expect(x).toHaveBeenCalledWith(someParams);, it requires a spy to be used. However, I am unsure of how to spy ...

Strategies for Obtaining a Response Following a Function Execution in React JS

Hello, I am encountering an issue where I am calling a function and trying to get a response, but it is returning undefined. The response is being passed from the parent component to the child component. Here is the code for the component: import React fr ...

Test your unit by providing feedback to the personalized modal pop-up

Currently, I am working on a unit test within Angular where I need to evaluate the functionality of the save button. My goal is to have the 'save' option automatically selected when the user clicks on the button, and then proceed to execute the s ...

What steps can be taken to resolve the error message "Using 'null' as an index type is not allowed."?

In my TypeScript code, I have a variable called lang declared as a string type value, and a variable called direction declared as an object with two elements. I also have a function that is supposed to return the value of the direction object based on th ...

Is your TypeScript spread functionality not functioning as expected?

I'm new to TypeScript, so please forgive me if I've made an error. On a guide about TypeScript that I found online, it states that the following TypeScript code is valid: function foo(x, y, z) { } var args = [0, 1, 2]; foo(...args); However, w ...

Incorporate a background image into mat-dialog

I've been struggling to set a background image on my mat-dialog, but for some reason it's not showing up at all. I attempted using a panelClass as well, but still no luck. .custom-panel .mat-dialog-container { background-image: url("../. ...

Testing Angular HTTP error handlers: A comprehensive guide

Below, you will find an example of code snippet: this.paymentTypesService.updatePaymentTypesOrder('cashout', newOrder).subscribe(() => { this.notificationsService.success( 'Success!', `Order change saved successfully`, ...

Updating from version 1.8.10 to 2.9.2 and encountering a build error in version 4.6.4

I currently have an angular application that is using typescript version 1.8.10 and everything is running smoothly. However, I am interested in upgrading the typescript version to 2.9.2. After making this change in my package.json file and running npm inst ...

Unable to access or modify properties within a function passed as an argument

deleteDialog(item, func: Function) { this.dialogService .open(ConfirmDialogComponent, { context: { title:"Are you sure?", cancelClss: "info", confirmClss: "danger", }, ...

What is the process of mapping an array of elements for a React component using TypeScript?

Check out my unique component: import React, { FunctionComponent as FC } from 'react'; type shapeMidNumbersInput = { arrMidNumbers: Array<number> }; const MidNumbers: FC<shapeMidNumbersInput> = ({ arrMidNumbers }): Array<Element ...