I am working on NodeJS/Express project. Running it on localhost I am trying to render a view on the client-side. But I get file not found error.
The javascript is located in /public/js folder. The view i am trying to render in views/view1.ejs
I tried
window.location('/view1')
window.location.replace('/view1')
Getting 404 error Not Found in either case.
You need to provide the url(route) instead of the path of the file. The window.location.replace takes a url(resource) as a parameter not a file. Declare this inside your index.js route file.
router.get("/view1",function(req,res,next){
res.render("view1")
});
Related
I want to use ReactDOMServer.renderToStaticMarkup to create a static website, but I only want to generate the html string once during build instead of dynamically for every request
Here are the relevant docs, but they don't go into much detail on implementation https://reactjs.org/docs/react-dom-server.html#rendertostaticmarkup
What is the best practice for using react to generate html one time during build instead of dynamically on every page request? I am using webpack.
For anyone who comes here looking for answers, here's how I did it:
Create a separate webpack config file for your SSR react like webpack.ssr.js. This file will have the same config you'd normally have for react SSR.
In the index.js file where you'd usually have ReactDOM.render, run the ReactDOMServer.renderToStaticMarkup function.
In the index.js file, write the html string to a file:
const html = ReactDOMServer.renderToStaticMarkup(App);
fs.writeFile("index.html", html, (err) => {
if (err)
console.log(err);
else {
console.log("File written successfully\n");
}
});
After every build, execute the build file as a node script. For example node build.js. I'd recommend doing this in package.json as a postbuild script. For example:
postbuild: "node build.js"
The fs.writeFile will update the index.html file each time you build, so you'll just need to serve index.html like you would with any other static website.
For css modules, you'd use something like isomorphic-style-loader instead of the regular style-loader.
If you are using something like react-router, you'll need to iterate through all your routes and run ReactDOMServer.renderToStaticMarkup and fs.writeFile for every route. Then you'd serve the different html files with server side routing.
This will also work for normal SSR using ReactDOMServer.renderToString, especially if you don't need dynamic SSR based on something like an ID. For generating the loading screen server side, this is great and there's really no reason to generate html dynamically at runtime.
I have a problem with using routes in my application, it is a template built using Shopify CLI, React and Shopify App Bridge guided by this documentation here.
Every route I trigger does get sent to the _app.js file within my project as I can log most of the output in the console, but I can't get it to actually include paths of subpages in my apps like https://{apphost}/custompage will not navigate to custompage but an error handler and the custompage gets included in the query. The route and pathname fields of the props return
{
...
router: "_error",
pathname: "_error ",
...
}
instead of
{
...
router: "custompage",
pathname: "custompage",
...
}
I expected the above to be the result but it isn't. But the custompage url does however appear in the asPath field like this asPath: "/custompage?hmac={hmac}&host={host}&shop={shop}" pretend everything in {} has actual information.
The query field gets the fields it needs as it does on a working page. So the main issue is just routing.
With this in mind I have concluded that maybe I have issues on my side and triggering the server side routes handler, but I do not know where to start redirecting to exact pages instead of the index page that came with the boilerplate code. And I looked on their documentation but they skip most parts that are required to actually explain handling routing with their boiletplate codes. I do not want to edit major functions because I am worried they might stop the whole app from working but I need to be able to handle routes on the app without getting the An unexpected error has occurred. error when trying to route to subpages. Even extensions to whitelisted urls within my app trigger that error, so I think I need help with adding routing to the app or server.
Can anyone help me figure out what I am missing?
I am still new to Shopify but I can say that working with Shopify is a nightmare.
I am not sure if this is the final solution but for now this works: make sure that all the files you are trying to route to have the same naming as your path.
If you are routing to https://{appURL}/subpath then your JS file should be subpath.js . I currently can only get it to work if the file is in the same folder as my _app.js. If I move the file from ./subpath to /dir/subpath then I need to change the extension to https://{appURL}/dir/subpath in my Shopify app settings. It seems to operate relative to the _app.js file's location so keep that in mind.
If you used the Shopify CLI and shopify node create to create your app then this could help with your routing 400 headache.
When I do SSR in my React apps (using Node.js / Express), and using Redux for state, I always end up with a similar to window.__PRELOADED_STATE__ = {....}
This output is something rendered together with the generated html code from renderToString but I'm wondering if there is a way to get that preloaded state variable inside a "virtual" js file instead (that can be referenced in my main layout template file), just to make the source code cleaner, without having to do the same rendering process twice?
I currently do my SSR via a middleware that I've setup in my Node.js/Express app.
Anyone has any ideas or recommendations?
Thanks
I have a expressJs setup which looks like this:
// Imports...
const app: express.Application = express();
const port: number = 3001;
const listener = new StatementListenerAPI();
app.use('/listen', listener.getRouter());
app.use('/welcome', router);
if (fs.existsSync('./client')) {
// Running in prod environment with pre built client directory. Serve this.
app.use(express.static('./client'));
}
app.listen(port);
So I have some routers connected to the express app, and at the bottom I declare that the directory client should be served statically. This directory contains an index.html as well as lots of JS, CSS and PNG files. However, no matter which URL I try to access from the express server, it always shows the code of the index.html within the statically served directory. The references to the JS and CSS files used inside the index.html also just return the code of the index.html.
I am using ExpressJS 4.16.3
What am I doing wrong?
Edit: So technically it works if using __dirname + '/client' instead of ./client. What I am now getting is that, when making GET requests from e.g. Postman (therefore "hand-crafting" the HTTP requests), I am always getting the correct results. If I call the resources from within my web browser, it still always shows the website (resolves the index.html). However, now all resources like JS and CSS scripts are being resolved properly, so apperantly Chrome resolves those dependencies properly, I am just wondering why I am still getting the contents of index.html as result when requesting some of the assets or some of the express endpoints via Chrome. API calls via code are working fine, so its only why manual chrome requests show this weird behaviour, at this point I am only asking out of curiosity.
Answer to your original question:
The path supplied to express.static should be relative to the directory from where you launch your node process or an absolute path. To be safe construct an absolute path (ie from the current directory or file). For example:
app.use(express.static(__dirname + '/client'));
Regarding your followup question:
I assume this is because Chrome uses heavy caching and it thinks this folder should return the html file. You can try and reset all caches in Chrome, or just for the page.
I created an empty project with Node and I bought a complete template online.
I'm pointing the init of page on my index.html but the console give me back this error (As the console show in the image)
Image
By deleting the <!DOCTYPE HTML the error turns on the < HTML.
It seems like the server doesn't recognize it is an HTML file.
Here another screenshot to show root, index file, and the server JavaScript
root,index,server.js
The problem is that you are referencing stylesheets and other resources in your HTML, but in your server-side code you've set up a "catch-all" GET route that always responds with an HTML document. When the browser requests these resources, that "catch-all" route is matched and so it sends back HTML (instead of the actual requested resource).
One solution to this is to simply include the express.static() middleware before your route handlers so that your page assets get transferred correctly.