Express doesn't render react - node.js

Im trying to create server-side to my new React project.
I have some issue, when I send my HTML file using app.get , it renders the html file without the react component, so all I see is just a blank page.
im trying to render index.js.
this is my serverside code:
const express= require('express');
const path = require("path");
const app=express();
app.use(express.static('build'));
app.use(express.urlencoded({extended:false}));
app.get('*', function(req, res) {
res.sendFile(__dirname + '/build/index.html');
});
app.listen(3000,function(){
console.log("Server is on");
});
my index.js code:("App" is my main component)
import React from 'react';
import ReactDOM from 'react-dom';
import App from "./App"
import { BrowserRouter, Routes, Route } from "react-router-dom";
ReactDOM.render(
<BrowserRouter>
<Routes>
<Route path="*" element={() => <App />} />
</Routes>
</BrowserRouter>,
document.getElementById('root')
);
HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Rubik">
<link rel="stylesheet" href="path/to/font-awesome/css/font-awesome.min.css">
<link rel="stylesheet" href="styles.css" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta
name="description"
content="Web site created using create-react-app"
/>
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<title>React App</title>
</head>
<body>
<div id="root"></div>
</body>
<script src="../src/index.js"></script>
</html>
What am I doing wrong? Thanks!

Related

MERN deploy script bundles on render

All my code compiles into dist folder. Client by CopyWebpackPlugin, server by tsc. and it looks like this. HTML sends app.get("*", (req, res) => { res.sendFile(path.join(__dirname, "client", "public", "index.html")); }); For static files i tried app.use("/static", express.static(path.join(__dirname, "client"))); app.use(express.static(path.join(__dirname, "client", "public"))); etc. Add all variants of scripts connection
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link href="https://fonts.googleapis.com/css2?family=Roboto&display=swap" rel="stylesheet" />
<title>Document</title>
</head>
<body>
<div id="root"></div>
<script src="/bundle.js"></script>
<script src="/client/public/bundle.js"></script>
<script src="/static/bundle.js"></script>
<script src="/static/public/bundle.js"></script>
</body>
</html>
And all my bundle.js files looks like this deployed app. How i suppose to add script bundles? Repo https://github.com/Dimkosyanklg/Cards-Test
Can't figure it out

Does Tailwind CSS work with express sendFile?

I am trying to send a html file through express but it is not able to include tailwindcss
I did all the set up correctly (at least that's what I think)
Is sendFile not capable of sending tailwindcss
This is the express setup
// express setup
const app = express();
const port = 9000;
app.use('/static', express.static('static'))
the endpoint
app.get("/", (req, res)=>{
res.sendFile(path.join(__dirname, "/template/home.html"))
});
html file
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Website</title>
<link rel="stylesheet" href="../static/output.css" />
</head>
<body>
<h1 class="text-sm">Doesn't Works</h1>
</body>
</html>
css file
#tailwind base;
#tailwind components;
#tailwind utilities;
tailwind config file
module.exports = {
content: ["*"],
theme: {
extend: {},
},
plugins: [],
}
and yes the path are correct it works with normal css but not with tailwindcss
I also don't want to use pug for it
Is there a way around it?
You can simple Use the Play CDN to try Tailwind right in the browser without any build step.
Add the Play CDN script tag to the <head> of your HTML file, and
start using Tailwind’s utility classes to style your content.
But remember :
The Play CDN is designed for development purposes only, and is not the
best choice for production.
<script src="https://cdn.tailwindcss.com"></script>
Folder & file structure :
app.js
const express = require("express");
const path = require("path");
const app = express();
const port = 9000;
app.use(express.static("./public"));
app.get("/", (req, res) => {
res.sendFile(path.join(__dirname, "/public/home.html"));
});
app.listen(port, () => {
console.log(`Server is listening at http://localhost:${port}`);
});
home.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script src="https://cdn.tailwindcss.com"></script>
<title>Express & TailwindCss</title>
</head>
<body>
<div class="flex items-center justify-center h-screen flex-col gap-5">
<h1 class="text-5xl font-bold underline text-green-500">
Express with TailwindCss
</h1>
<h3 class="text-blue-900 text-3xl font-bold">It does works! ;-)</h3>
</div>
</body>
</html>
Output :

router.post is not rendering a page

I am learning node. I am stuck where I can render a view from get method but not from post.
app.js
var express = require("express");
var path = require("path");
var favicon = require("serve-favicon");
var logger = require("morgan");
var cookieParser = require("cookie-parser");
var bodyParser = require("body-parser");
var test = require("./routes/test");
app.set("views", path.join(__dirname, "views"));
app.set("view engine", "ejs");
app.use(test);
test.js
var express = require("express");
var router = express.Router();
router.get("/test", function(req, res, next) {
res.render("testView1"); //working OK
});
router.post("/test", function(req, res, next) {
console.log("Its a test") // Working OK
res.render("testView2",{
// some data to be posted
}); // not redirecting to testView2
});
module.exports = router;
post /test is to be called on a button click event. it should render testView2 page where I have to display some data. I am stuck with this rendering kind of thing......Please help me to learn this.
Thanks,
Sunil
testView2.ejs is just a simple plain html template as of now
testView2.ejs
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title></title>
</head>
<body>
<h1>testview 2</h1>
</body>
</html>
testView1.ejs
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title></title>
<% include ./scriptLinks/headerLinks.ejs %>
</head>
<body>
<h1>TestView 1</h1>
<button id="btn-test">Test</button>
<script>
$("#btn-test").on("click", function(e) {
e.preventDefault();
$.post("/test", { name: " some data" });
});
</script>
</body>
</html>
and yes All ejs files are in view folder.
Thank you.
Of course it will not work. $.post is ajax request + it's asynchronous so it will not make browser navigate to /test route with post method in header.
Make testView1.ejs have such content:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title></title>
<% include ./scriptLinks/headerLinks.ejs %>
</head>
<body>
<h1>TestView 1</h1>
<form method="post" action="/test">
<button id="btn-test">Test</button>
</form>
</body>
</html>
but if You insist on ajax call - so do this:
1) testView2.ejs must consist of only this (no headers, no body, no html tags):
<h1>testview 2</h1>
2) testView1.ejs :
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title></title>
<% include ./scriptLinks/headerLinks.ejs %>
</head>
<body>
<h1>TestView 1</h1>
<form method="post" action="/test">
<button id="btn-test">Test</button>
</form>
<script>
$(function() {
$("from").on('submit', function(e) {
e.preventDefault();
var method = $[$(this).attr('method').toLowerCase()];
if (!method) method = 'get';
method(
$(this).attr('action'),
{ name: " some data" },
function(response) {
$('body').html(response);
});
});
});
</script>
</body>
</html>
warning: I don't recommend to inject html response to body - it may lead to unexpected behavior, since You don't seem to have enough frontend experience

React app hosted on heroku goes blank when clicked refresh

I hosted a MERN app which uses webpack on heroku. React Routing works fine on local host. But on heroku, when I click refresh on /any-path page is blanked out.
Console shows an error "The character encoding of the plain text document was not declared. The document will render with garbled text in some browser configurations if the document contains characters from outside the US-ASCII range. The character encoding of the file needs to be declared in the transfer protocol or file needs to use a byte order mark as an encoding signature."
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Raven</title>
<link rel="icon" type="image/png" href="/assets/img/logo.png">
<!-- <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans:300,400,600"> -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500">
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
</head>
<body>
<div id="app"></div>
<script type="text/javascript" src="/js/app.js"></script></body>
</html>
index.js
import React from 'react';
import { render } from 'react-dom';
import {Bootstrap, Grid, Row, Col} from 'react-bootstrap';
import {
BrowserRouter as Router,
Route,
Link,
Switch
} from 'react-router-dom'
import App from './components/App/App';
import NotFound from './components/App/NotFound';
import Home from './components/Home/Home';
import './styles/styles.scss';
render((
<Router>
<App>
<Switch>
<Route exact path="/" component={App}/>
<Route exact path="/login" component={Home}/>
<Route component={NotFound}/>
</Switch>
</App>
</Router>
), document.getElementById('app'));
server.js
app.use(express.static(path.resolve(__dirname, '../dist')));
app.get('*', function (req, res) {
res.sendFile(path.resolve(__dirname, '../dist/index.html'));
res.end();
});

How do I fix the React Router 'unexpected token <' error?

There is a problem with my react.js / node.js app. I use React-routers in my app, and have very nasty mistake.
Index route works, everything is fine.
Routes like "/something" also work
But routes like "/something/something" don't work:
(Next images are in comment to this question)
[When I first loaded this page][3]
[When I reloaded page][4]
My code:
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Boox</title>
<meta name="theme-color" content="teal">
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="http://fonts.googleapis.com/icon?family=Material+Icons" />
<link type="text/css" rel="stylesheet" href="./plugins/css/normalize.css" />
<link type="text/css" rel="stylesheet" href="./plugins/css/animate.css" />
<link type="text/css" rel="stylesheet" media="screen, projection" href="./plugins/materialize/css/materialize.min.css" />
</head>
<body>
<div id="root">
</div>
<script src="./plugins/js/jquery.js"></script>
<script src='./plugins/materialize/js/materialize.min.js'></script>
<script src="./dist/bundle.js"></script>
</body>
index.js:
import React, {Component} from 'react';
import ReactDOM from 'react-dom';
import {Router, Route, Link, browserHistory, IndexRoute} from 'react-router'
import App from './App.js';
import Main from './components/Main.js';
import NotFound from './components/NotFound.js';
import Users from './components/user/Users.js';
import Profile from './components/user/Profile.js';
// components
import Signup from './components/user/auth/Signup.js';
import Signin from './components/user/auth/Signin.js';
import Editor from './components/user/write/Editor.js';
import Write from './components/user/write/Write.js';
// styles
require('./less/common.less');
ReactDOM.render((
<Router history={browserHistory}>
<Route path="/" component={App}>
<IndexRoute component={Main} />
<Route path="signup" component={Signup} />
<Route path="signin" component={Signin} />
<Route path="write" component={Write}>
<Route path=":id" component={Editor} /> // This doesnot work :(
</Route>
<Route path="users" component={Users}>
<Route path=":id" component={Profile} /> // This doesnt work :(
</Route>
</Route>
<Route path=":id" component={NotFound} />
</Router>
), document.getElementById('root'))
Users.js:
import React, {Component} from 'react';
import {Router, Route, Link, browserHistory, IndexRoute} from 'react-router'
export default class Users extends Component {
constructor() {
super()
this.state = {
}
}
render() {
return (
<div>
<h1>TEST USERS ROUTE</h1>
{this.props.children}
</div>
)
}
}
Server.js also contain this:
app.get('*', (req, res) => {
res.sendFile(path.resolve(__dirname, 'index.html'));
})
I would be glad to any advice. Thanks.
The issue you are seeing is related to trying to load a resource like a js script or css script and your express server doesn't handle that route. which then means it returns the html file. and javascript goes ugh I dono what < is.. if you notice < is the first character in the html file.
To give a complete answer I would need to see what your server file is to see which route is missing. But my guess would be any of these are the culprit
<link type="text/css" rel="stylesheet" href="./plugins/css/normalize.css" />
<link type="text/css" rel="stylesheet" href="./plugins/css/animate.css" />
<link type="text/css" rel="stylesheet" media="screen, projection" href="./plugins/materialize/css/materialize.min.css" />
<script src="./plugins/js/jquery.js"></script>
<script src='./plugins/materialize/js/materialize.min.js'></script>
<script src="./dist/bundle.js"></script>
basically any import that you have that has a local path. You need to make sure you have a route on the server that accepts it.
Problem solved.
All my links were relative ./plugins/css/normalize.css, and when I tried to load localhost/write/123, they (links) were trying to load localhost/write/plugins/css/normalize.css.
I have removed dots /plugins/css/normalize.css and problem solved!
Thanks for advices.
The issue is about using relative paths inside react code (very common approach), could be fixed by adding this:
<base href="/" />
Inside head section of your index.html file.

Resources