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.
Related
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!
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();
});
I got an Angular2 project that was developed by a different person and I need to run it. When I do, using npm start I get the server to run but the component, called my-app is not rendering on the page.
This is the index.html:
<html>
<head>
<base href='/'>
<title></title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="styles.css">
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
<link href="c3.css" rel="stylesheet" type="text/css">
</head>
<body>
<my-app>Loading......</my-app>
</body>
</html>
This is app.components.ts:
import { Component } from '#angular/core';
import { AuthenticationService } from './authentication.service';
import { Router } from '#angular/router';
#Component({
selector: 'my-app',
templateUrl: 'app/app.component.html',
styleUrls: ['app/app.component.css']
})
export class AppComponent {
title = '';
isProd:boolean;
constructor(private authenticationService: AuthenticationService, private router: Router) {
this.isProd = false;
}
In the template for my-app, which is app/app.component.html I put a simple div for testing:
<div><h1>app components</h1></div>
When running this I can see the Loading..... which is in index.html but not the contents of app/app.component.html.
What am I missing?
I can't see if you are loading angular and your transpiled ts anywhere in index.html. You need to load all required dependeny for run angular2 app in index.html and allso your transpiled ts.
Note:- you need to put base tag after all you link to load css.
<title></title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="styles.css">
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
<link href="c3.css" rel="stylesheet" type="text/css">
<base href='/'>
I am trying to learn angular 2, I am learning from the official website 5 min quick start https://angular.io/guide/quickstart
When I do npm start I get only loading... being displayed in the browser
I am using typescript 1.8
node 4.4.7
npm 2.15.8
using windows
has you can see from the above picture that it is not going to the app.component.ts file
import { bootstrap } from '#angular/platform-browser-dynamic';
import { AppComponent } from './app.component';
bootstrap(AppComponent);
my main.ts file
<html>
<head>
<title>Angular 2 QuickStart</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="styles.css">
<!-- 1. Load libraries -->
<!-- Polyfill(s) for older browsers -->
<script src="node_modules/core-js/client/shim.min.js"></script>
<script src="node_modules/zone.js/dist/zone.js"></script>
<script src="node_modules/reflect-metadata/Reflect.js"></script>
<script src="node_modules/systemjs/dist/system.src.js"></script>
<!-- 2. Configure SystemJS -->
<script src="systemjs.config.js"></script>
<script>
System.import('app').catch(function(err){ console.error(err); });
</script>
</head>
<!-- 3. Display the application -->
<body>
<my-app>Loading...</my-app>
</body>
</html>
my index.html file
import { Component } from '#angular/core';
#Component({
selector: 'my-app',
template: '<h1>My First Angular 2 App</h1>'
})
export class AppComponent { }
my app.component.ts file
The rest of the files are the same has given in the tutorial all config files.
My onSubmit function is not working with a website I made using a bootstrap template, specifically this one https://wrapbootstrap.com/theme/unify-responsive-website-template-WB0412697. It just refreshes the page, deleting whatever is in there. I have tried all combinations of the following:
Replacing onSubmit with onSuccess.
Moving my function inside the render before the return statement.
Adding parentheses to the handleSubmit function within the
Replacing e.preventDefault() with e.stopPropagation()
I am using nodejs, express and react, and am new to all 3.
I find it worth mentioning that I do not require('react-dom') nor use ReactDOM anywhere, which is weird to me because I always used it when I did the tutorials to learn react.
I believe I have read every similar problem on stack overflow, but nothing seems to be working. Here are my files in the order in which they are executed
app.js
var routes = require('./routes/index');
app.use('/', routes);
routes/index.js file
var express = require('express');
var router = express.Router();
router.get('/', function(req, res, next) {
res.render('index');
});
module.exports = router;
views/index.fsx jsx
var React = require('react');
var LoginForm = React.createClass({
getInitialState: function() {
return {username: '', password: ''};
},
handleUsernameChange: function(e) {
this.setState({username: e.target.value});
},
handlePasswordChange: function(e) {
this.setState({password: e.target.value});
},
handleSubmit: function(e) {
e.preventDefault();
},
success : function () {
alert('Success');
},
fail : function () {
alert('Fail');
},
render: function() {
return (
<form onSubmit={this.handleSubmit} className="loginForm">
<div className="input-group">
<input type="text" className="form-control" placeholder="Username" value={this.state.username} onChange={this.handleUsernameChange} required autofocus />
<input type="password" className="form-control" placeholder="Password" value={this.state.password} onChange={this.handlePasswordChange} required />
<button type="submit" className="btn-u btn-u-lg col-xs-12 col-sm-offset-5 col-md-offset-1 col-lg-offset-2">
Sign in <i className="fa fa-sign-in" />
</button>
</div>
</form>
);
}
});
var Welcome = React.createClass({
render: function() {
return (
<html>
<head>
<link rel='stylesheet' type='text/css' href='//fonts.googleapis.com/css?family=Open+Sans:400,300,600&subset=cyrillic,latin' />
<link rel="stylesheet" href="assets/plugins/bootstrap/css/bootstrap.min.css" />
<link rel="stylesheet" href="assets/css/style.css" />
<link rel="stylesheet" href="assets/css/headers/header-default.css" />
<link rel="stylesheet" href="assets/css/footers/footer-v1.css" />
<link rel="stylesheet" href="assets/plugins/line-icons/line-icons.css" />
<link rel="stylesheet" href="assets/plugins/font-awesome/css/font-awesome.min.css" />
<link rel="stylesheet" href="assets/plugins/sky-forms-pro/skyforms/css/sky-forms.css" />
<link rel="stylesheet" href="assets/plugins/sky-forms-pro/skyforms/custom/custom-sky-forms.css" />
<link rel="stylesheet" href="assets/css/pages/page_search.css" />
<link rel="stylesheet" href="assets/css/theme-colors/teal.css" id="style_color" />
<link rel="stylesheet" href="assets/css/theme-skins/dark.css" />
<link rel="stylesheet" href="assets/css/custom.css" />
<link rel="stylesheet" href="assets/css/homepage-style.css" />
</head>
<body>
<div>
<LoginForm />
</div>
<script type="text/javascript" src="assets/plugins/jquery/jquery.min.js" />
<script type="text/javascript" src="assets/plugins/jquery/jquery-migrate.min.js" />
<script type="text/javascript" src="assets/plugins/bootstrap/js/bootstrap.min.js" />
<script type="text/javascript" src="assets/plugins/back-to-top.js" />
</body>
</html>
);
}
});
module.exports = WelcomePage; // I'm not entirely sure what module.exports does
You need to change e.stopPropagation(); with e.preventDefault(); This will stop the page refresh.
Also,
stopPropagation stops the event from bubbling up the event chain.
preventDefault prevents the default action the browser makes on that event.
Move your html code in a separate file and render your app like the jsfiddle example that I created for you. https://jsfiddle.net/antony_z/7jLqxm2p/
Maybe try adding .bind(this) to this.handleSubmit, to have this.handleSubmit.bind(this)
Keep :
onSubmit
e.preventDefault()
I am attempting to answer my own question here because it was too long for a comment. But regarding your suggestion to put my HTML in it's own file...
My view engine is setup for jsx files. I am going to try what you did by doing this:
npm install consolidate
npm install swig
In app.js I will put:
var cons = require('consolidate');
at the top. Then for my view engine setup I will configure it like:
app.engine('html', cons.swig);
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'html');
So now how do I setup my routes/index.js file? I'm guessing it should be something like:
var express = require('express');
var router = express.Router();
router.get('/', function(req, res) {
res.render('index');
});
So now I will have to create views/index.html (rather than views/index.jsx like before). I inserted the HTML from your JSfiddle into the index.html file, but where do I put the code containing the LoginForm and ReactDOM stuff? I think I would be able to create a file in public/js/welcome-page.jsx and then include it at the bottom, but then other people can see my react code and onSubmit function, which is insecure right?