Search code examples
expressvue.jsaws-amplifyhistory.js

Page refresh or direct load shows blank screen


I've read a number of solutions to this same problem, but none have worked for me. So here it goes.

I have a Vue 2 app using Express that runs on AWS Amplify. When I run my app locally in 'dev' mode (npm run serve) and 'start' mode (npm run build && node server.js), everything works fine.

The problem shows up when I deploy to Amplify. I can click nav buttons, go back, and go forward, all of which send me to the correct URL. However, the moment I refresh the page or manually enter a valid URL in the browser, the screen goes blank and the browser URL shows https://dontblowup.co/index.html.

Below is my server.js file:

const express = require('express')
const path = require('path')
const history = require('connect-history-api-fallback')

const app = express()
const port = process.env.PORT || 8080
const buildLocation = 'dist'
const staticFileMiddleware = express.static(path.resolve(__dirname, buildLocation))

app.use(staticFileMiddleware)
app.use(history())
app.use(staticFileMiddleware)

app.get('*', function (req, res) {
  res.sendFile(path.resolve(__dirname, buildLocation, 'index.html'))
})

app.listen(port, () => {
  console.log(`App listening to port ${port}...`)
  console.log('Press Ctrl+C to quit.')
})

The solutions I found included using the history package in the server.js file and using the staticFileMiddleware before and after using history(). I also have 'history' mode set in the Vue app's router.js file (see below).

import Vue from "vue";
import VueRouter from "vue-router";

import Index from "./views/Index.vue";
import MainFooter from "./layout/MainFooter.vue";

import DashboardLayout from "@/layout/DashboardLayout.vue";
import Analytics from "@/views/Analytics.vue";
import TradeSheet from "@/views/TradeSheet.vue";
import KellyCriterionCalculator from "@/views/KellyCriterionCalculator.vue";
import PositionBuilder from "@/views/PositionBuilder.vue";

Vue.use(VueRouter);

export default new VueRouter({
  mode: 'history',
  routes: [
    {
      path: "/",
      name: "Index",
      components: { default: Index, footer: MainFooter },
      props: {
        footer: { backgroundColor: "black" }
      },
      meta: { requiresAuth: false }
    },
    {
      path: "/dashboard",
      redirect: "/dashboard/analytics",
      name: "Dashboard",
      component: DashboardLayout,
      meta: { requiresAuth: true },
      children: [
        {
          path: "/dashboard/analytics",
          name: "Analytics",
          component: Analytics
        },
        {
          path: "/dashboard/trade-sheet",
          name: "Trade Sheet",
          component: TradeSheet
        },
        {
          path: "/dashboard/risk-budget-calculator",
          name: "Risk Budget Calculator",
          component: KellyCriterionCalculator
        },
        {
          path: "/dashboard/trade-analyzer",
          name: "Trade Analyzer",
          component: PositionBuilder
        }
      ]
    }
  ],
  scrollBehavior: to => {
    if (to.hash) {
      return { selector: to.hash };
    } else {
      return { x: 0, y: 0 };
    }
  }
});

At this point I'm convinced there's something wrong with Amplify or Namecheap (where my DNS is configured). Unfortunately I haven't found anyone with the same issues using the same tech, so hopefully someone here can help.

Cheers!


Solution

  • You need to set up it on the Amplify Console

    • Navigate to the Amplify Console
    • On the left menu click on "Rewrites and redirects"
    • Click on Edit
    • Add the rule:
       Source: </^[^.]+$|\.(?!(css|gif|ico|jpg|js|png|txt|svg|woff|ttf|map|json)$)([^.]+$)/>
       Target: /
       Type: 200
      

    You can read more about it here

    Go to section: Redirects for Single Page Web Apps (SPA)

    Most SPA frameworks support HTML5 history.pushState() to change browser location without triggering a server request. This works for users who begin their journey from the root (or /index.html), but fails for users who navigate directly to any other page. Using regular expressions, the following example sets up a 200 rewrite for all files to index.html except for the specific file extensions specified in the regular expression.