app.use( express.static(path.resolve(__dirname, './../public')) );
app.use(express.static(path.resolve(__dirname, './../public/js') )); //если убрать это
app.use(express.static(path.resolve(__dirname, './../public/css'))); //и это то работать не будет
<base href="http://localhost:<PORT>">
//так
app.use("/static/*", express.static(__dirname + './../public' ));
app.use("/static/*", express.static(__dirname + './../public/js' ));
app.use("/static/*", express.static(__dirname + './../public/css'));
//вот так
app.use("/static/", express.static(__dirname + './../public' ));
app.use("/static/", express.static(__dirname + './../public/js' ));
app.use("/static/", express.static(__dirname + './../public/css'));
//и так
app.use("/static", express.static(__dirname + './../public' ));
app.use("/static", express.static(__dirname + './../public/js' ));
app.use("/static", express.static(__dirname + './../public/css'));
app.use(express.static(__dirname + './../public' ));
app.use(express.static(__dirname + './../public/js' ));
app.use(express.static(__dirname + './../public/css'));
app.use("/main", express.static(__dirname + './../public' ));
app.use("/main", express.static(__dirname + './../public/js' ));
app.use("/main", express.static(__dirname + './../public/css'));
Отрендерите пустые компонент (или как оно там называется) а потом просто догружайте данные. Идея в том чтобы выдать чистый интерфейс там, где он будет догружаться, а данные заполнить в последствии. Я не знаю что вы используете для своего spa. В реакте, например, это делается с помощью хуков эффекта.