Express static files URL changes based on route - javascript

I have create-react-app thats using react-router-dom. I'm also using express server-side-rendering for SEO. Below is my simple express config. When I got to the '/' route or any of the first-level routes ("/contact", "/blog", etc), it works as intended. The static files come in as:
"http://localhost:8080/static/css/main.ec91a01d.css".
But when I navigate to any multi-level routes ("/blog/blog-post-1"), it adds the first route to the static files URl ex:
http://localhost:8080/blog/static/js/main.d9a1d852.js
What am I doing wrong? Also, the folder structure is that of a regular Create-react-app. Im serving my index.html from the build folder and my styles/js from build/static.
Project
----build
----public
...etc
And my server.js
const express = require('express');
const path = require('path');
const ssr = require('./ssr.mjs');
const app = express();
const crawler = async (req, res) => {
const isBot = req.get('User-Agent').indexOf('Googlebot') > -1 ||
req.get('User-Agent').indexOf('googlebot') > -1;
if (isBot) {
const { html } = await ssr(`http://www.example.com${req.path}`);
return res.status(200).send(html);
}
res.sendFile(path.join(__dirname + '/build/index.html'));
};
app.use(express.static('build'));
app.get('/', crawler);
app.get('/process', crawler);
app.get('/work', crawler);
app.get('/contact', crawler);
app.get('/blog', crawler);
app.get('/blog/create-post', crawler);
app.get('/blog/:id', crawler);
app.get('/services', crawler);
app.get('/services/:id', crawler);
app.get('/payments', crawler);
const PORT = process.env.PORT || 8080;
app.listen(PORT, () => console.log('Server started. Press Ctrl+C to quit'));

You seem to be fetching your ressources with relative paths in your index.html, e.g.
<script src="./static/js/main.d9a1d852.js"></script>
What you want are absolute paths:
<script src="/static/js/main.d9a1d852.js"></script>
Notice the missing . at the beginning of the path.

Related

Exposing html file to express.static middleware on Replit

On Replit, rendering the html file using res.sendFile inside a app.get works perfectly fine, AND I am able to add logos, styles, and js logic file by passing in express.static middleware.
BUT when I try to also include the html as a static file passed to express.static middleware, the page does not render.
Here's the replit: https://replit.com/#yanichik/NodeJSandExpressFullCourseFCC#02-express-tutorial/app.js
Renders as expected when html passed in with res.sendFile:
const express = require('express'); const path = require('path');
const app = express();
// setup static & middleware // static -> file that server does NOT
have to change app.use(express.static(path.resolve(__dirname,
'./public')))
app.get('/', (req, res) => { res.sendFile(path.resolve(__dirname,
'./navbar-app/index.html')) })
app.all('*', (req, res) => { res.status(404).send('Resource not
found.') })
app.listen(5000, () => { console.log('Server listening on port
5000...') })
module.exports = app;
Now, DOES NOT render as expected when html passed in with express.static middleware:
const express = require('express'); const path = require('path');
const app = express();
// setup static & middleware // static -> file that server does NOT
have to change app.use(express.static(path.resolve(__dirname,
'./public')))
// app.get('/', (req, res) => { //
res.sendFile(path.resolve(__dirname, './navbar-app/index.html')) // })
app.all('*', (req, res) => { res.status(404).send('Resource not
found.') })
app.listen(5000, () => { console.log('Server listening on port
5000...') })
module.exports = app;
You have to specifically request for the statically exposed files like so:
https://baseURL.com/navbar-app/index.html
When you comment out get routes.
If you have your get route uncomented route then
https://baseurl.com
Will return the html file

Heroku url routes can only be reached programmatically

Sorry if this question is vague but I really don't know what code to present.
I have a Heroku webpage which is running fine. I am using reach-router to navigate from one page to another on button clicks: <button onClick={() => navigate('/intro')}>Click</button>. When I do this the url changes appropriately and my content is visible. However if I type in the exact same url I get an error saying Cannot GET /intro. This error even happens if I use the button click to navigate and then reload the page.
It's my understanding that app.use(express.static('build')); will serve my static files.
So why can I visit pages if I start at my root url and navigate from there but I can't enter a url and travel to that page?
The website is live here https://build-a-wedding.herokuapp.com/
Adding more details on my server.js
const express = require('express');
const bodyParser = require('body-parser');
const path = require('path');
const cors = require('cors');
const sessionMiddleware = require('./modules/session-middleware');
require('dotenv').config();
const app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(sessionMiddleware);
app.use(cors());
// Serve static files
app.use(express.static('build'));
app.use(express.static(path.resolve(__dirname, '..', 'build')));
const users = require('./routes/users.router');
const dataFetch = require('./routes/data.router');
const venues = require('./routes/venues.router');
app.use('/users', users);
app.use('/location', dataFetch);
// app.use('/', auth);
app.use('/venues', venues);
const PORT = process.env.PORT || 3001;
app.listen(PORT, () => {
console.log(`Listening on port: ${PORT}`);
});
When I navigate programmatically here is what i see for my sources
When I type in the same URL here is the source tree
Just create a static.json file at the root of your React project with the following content:
{
"root": "build/",
"clean_urls": false,
"routes": {
"/**": "index.html"
}
}
This question is possibly duplicated
Make sure that your express app are listening to these routes and sending response to them.
Example:
app.get('/intro', function (req, res) {
res.send(pathToPage);
});

How do I run two separate files on different ports with webpack?

There are two entry points.
main.js
index.js
and there are two html files
main.html
index.html
When building, I have js files connected to Html. index.js is linked to index.html and the like.
The task is to create two commands in the package.json file
start-index - starts index.html file on port 3000
start-main runs main.html file on port 8080
Each of them must run different Html with different connected files on different ports.
Please tell me how to do this?
From what I can understand, something like this may be helpful - I'm not sure why you would need two js files, you can probably just a framework like express, and just serve different files on different ports. Let me know if this is what you're looking for!
const express = require('express');
const path = require('path');
const app = express();
const secondaryApp = express();
const PRIMARY_PORT = process.env.PRIMARY_PORT || 3000;
const SECONDARY_PORT = process.env.SECONDARY_PORT || 8000;
const STATIC = path.join(__dirname, '../static/');
const HTML_FILE_PRIMARY = path.join(STATIC, 'index.html');
const HTML_FILE_SECONDARY = path.join(STATIC, 'index2.html');
app.use(express.static(STATIC));
secondaryApp.use(express.static(STATIC));
// Add routes to both apps
app.post('/route', function(req, res) {
res.status(200).end();
});
secondaryApp.post('/route', function(req, res) {
res.status(200).end();
});
// Set up both GET requests to index
app.get('/', (req, res) => {
res.sendFile(HTML_FILE_PRIMARY);
})
secondaryApp.get('/', (req, res) => {
res.sendFile(HTML_FILE_SECONDARY);
})
// Let both servers listen on their own ports
app.listen(PRIMARY_PORT, () => {
console.log("Primary app listening on port: "+PRIMARY_PORT);
})
secondaryApp.listen(SECONDARY_PORT, () => {
console.log("Secondary app listening on port: "+SECONDARY_PORT);
});

node, express, body-parser - can't read js file from src

may be its dumb question but I can't find answer yet. :(
I made app using create-react-app, and server file:
server.js
const express = require('express');
const bodyParser = require('body-parser');
const fs = require('fs');
const path = require('path');
const PORT = process.env.PORT || 3000;
const app = express();
const p = path.parse(__dirname);
app.use(express.static('public'));
app.get('/', (req, res) => {
const filePath = path.join(p.dir, 'src', 'index.js');
fs.readFile(filePath, {encoding: 'utf-8'},(err, data) => {
if (err) {
throw err;
}
res.send(data);
});
});
app.listen(PORT, () => {
console.log(`Started at port ${PORT}`);
});
tryied to read index.js file from app src directory but all i got in browser is plain text. I can only run static files from public directory. What i did wrong and how should i run js files of react app using express in node?
You need to send the index.html file that is built by react. A browser can only open a web page from a html file.
You need to first build your react app using npm run build
Then serve it with express with something like
app.get('*', (req,res) => {
res.sendFile('/build/index.html'); // wherever react creates the index.html
});
To give you a basic idea on express,
const express = require('express')
const app = express()
app.get('', (req, res) => {
res.render('index') // index is an html file or a template (ejs, hbs, etc..)
})
// You can't directly send js files
app.get('/info', (req, res) => {
res.render('info', {
title: 'info page',
message: 'welcome to the info page'
})
})
// You can't directly send js files
app.listen(3000, () => {
console.log('Server is up on port 3000.')
})
If you want to send json
const leaderboardHistory = require("relativepath/leaderboardHistory.json")
app.get("/leaderboardhistory", function(req, res){
res.render("leaderboardhistory", {leaderboardHistory : leaderboardHistory});
});

How to serve an image from Express.js to React

I am trying to serve up an image from my public directory on my node.js + express backend to the client side which is Reacts (create-react-app to be particular).
I have the typical file structure of
-public
-images
-image.jpeg
On my client side, I have an image tag with a relative path like so
<img src='/images/me.jpeg' alt="" />
My app.js for express looks like so
const express = require('express');
const path = require('path');
const bodyParser = require('body-parser');
const app = express();
const contactRouter = require('./routes/contact');
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use(express.static(__dirname + "/public"));
app.use(express.static(path.join(__dirname, 'client/build')));
//route handlers
app.use('/contact', contactRouter);
app.get('*', (req, res) => {
res.sendFile(path.join(__dirname + '/client/build/index.html'));
});
module.exports = app;
alas, I am not getting any luck with the image being served up. Any ideas for this? I am not sure if I also need an additional proxy for when I am in dev. I have tried this which likes in my src folder in react
const proxy = require('http-proxy-middleware');
module.exports = function (app) {
app.use(proxy('/images/*', { target: 'http://localhost:5000' }));
}
I appreciate the help guys!

Categories