Real URLS with Single Page Applications? - javascript

I was using react router for one of my projects, so react is frontend library and routes are managed by react router and backend views are in django and apis in django rest
So i was going through the react-router documentation and I came across this:-
Configuring Your Server
Your server must be ready to handle real URLs. When the app first loads at / it will probably work, but as the user navigates around and then hits refresh at /accounts/23 your web server will get a request to /accounts/23. You will need it to handle that URL and include your JavaScript application in the response.**
I was wondering how would this work with django views.

On the development server, you simply set up a route for everything that doesn't start with api/ or static/ to return your basic app.html file. Example
class AppHTMLView(View):
def get(self, request):
fn = os.path.join(settings.BASE_DIR, "app", "app.html")
with open(fn, 'r') as fh:
return HttpResponse(fh.read())
And on your production server, you configure Nginx accordingly. Something like this
...
location / {
root /var/www/example.com/static_files/;
try_files '' /app.html =404;
}
But that's not in any way specific to React, but common to all single page apps.

Related

hybrid SPA with Next js

The problem I'm trying to solve: there is a public part that requires ssr for seo. But there is also an application where seo is not needed and for it to be spa.
I have no experience with next js. So the question is, is it possible to "embed" a spa application in next js.
I will be happy to get any information
react-router-dom does not work with next js because of the hydration process
I would keep the two apps separate since they have different architectures, and it will be simpler that way. Sounds like your SPA may also be secured, which is why it does not need SEO.
A good technique can be be to build both apps to static content, then achieve public URLs like this:
https://www.example.com
https://www.example.com/public
Both built apps could potentially be deployed to a content delivery network. Another common option is to use a reverse proxy such as NGINX or Kong. This configuration uses NGINX to serve the SPA's static content, then routes requests to the Next.js app to a Docker container:
server {
server_name reverseproxy;
listen ssl 443;
location / {
root /usr/share/nginx/html;
index index.html;
}
location /public {
proxy_pass https://nextjsapp:3000/;
}
}

Issue with routing in react app

I have a web app. Back end with node and front end with React. Setup (simplified) goes like this:
index.js (the server)
client
package.json
The client
Now, the client folder contains a front end web application, its contents are basically same as what you get when you type create-react-app.
Inside client there is a build folder which I created by running npm run build from within the client folder.
Server
Now, the index.js from my main folder acts as the node server, inside it I have a line like:
app.use(express.static(__dirname + "/client/build"));
Using this approach I have merged my node server and a client front end application (located inside client folder). You can see I told the server to serve files from the client/build.
All was working fine, till I encountered this.
If I click a react button in my client app which manually calls my router using say:
this.props.router.push('/listmovies');
it correctly shows the page.
But if I type same page in URL address bar and hit ENTER I get error:
Cannot GET /listmovies
The latter error I am pretty sure comes from node server. Because there is no listener for listmovies in index.js (and there should not be). You see basically I think node is intercepting the call and giving me an error. Whereas in my former case where I called router.push I get a correct page.
I hope I managed to explain my problem. Can someone help how to solve this issue?
You have to make the express application redirect all requests to the main React file so react-router can take over. Something like this below the app.use.
app.get('*', function(req, res) {
res.sendFile(__dirname + '/client/build/index.html')
})
This basically handles all wildcards and points it to the index.html. Mind you if you are also implementing API routes on the express app have them above this wildcard statement because otherwise it will intercept them and treat them as client side react-router routes instead of server-side API routes.

How to connect an EmberJS front-end with an NodeJS Express API?

I'm working on a MEEN-stack (MySQL, EmberJS, Express, and NodeJS) project. I have never worked with Ember at all. My only front-end experience is jQuery.
The project is separated into folders, with the front-end (Ember) in one folder and the Express API in another. Front-end will handling loading in web-pages while sending requests to Express API for database requests / authentication / more.
I am currently able to connect the two servers via an explicit URL with jQuery's Ajax method in a webpage's static javascript file (along with allowing CORS and modifying the Ember environment file in app/config).
My confusion is that there is definitely a more elegant solution for connecting the two, but I'm lost on how to go about it.
From looking at tutorials, I have attempted adding an application.js file in the Ember Front-End app/adapters folder:
import DS from "ember-data";
export default DS.RESTAdapter.extend({
host: 'http://localhost:9029',
namespace: 'api'
});
But I don't have the knowledge to fully implement it or test it. What am I missing? How do I take advantage of the adapter file?
When you start ember use:
ember server --proxy 'http://localhost:9029'
Assuming that you node server is serving your api from http://localhost:9029 as you start the ember server with the proxy the ember-cli will spin up a very simple node proxy that will proxy your requests while you are developing.
Then you can remove the host from your adapter.js file
import DS from "ember-data";
export default DS.RESTAdapter.extend({
namespace: 'api'
});
Also if you want brevity:
ember s -pxy 'http://<YOUR LOCAL SERVER AND PORT>'

Ember app served from node.js using baseUrl/rootUrl with authentication

So, currently I have been using Ember cli to proxy to my api that is on a different port. I am trying to serve up a few routes using only node ('/', '/signIn', '/signUp'), and then once a user is authenticated through the '/signIn' route, serve up the ember app with a token.
As of now I am using 'baseURL' defined in my 'environment.js' of ember-cli, and my ember app is served to '/app/'.
I am getting confused on how one would go about serving up the ember app when a certain node route is accessed and the token is validated. In other words, I can visit my node routes fine, I can visit my ember routes fine using /app/, but am unsure of how to serve up the ember app once my server authenticates the user at '/signIn'. My reasoning for this, is that I do not want to serve up all the javascript assets to the client until I am sure they are an actual user. I am sure that this can be done using node and ember, but have not found much material online regarding such a configuration.
I have done a good amount of research, and the things that have caught my eye are 'baseURL' defined in CLI, 'rootURL' defined in Ember, and this from the Ember CLI page:
Integration
When using Ember inside another project, you may want to launch
Ember only when a specific route is accessed. If you’re preloading
the Ember javascript before you access the route,
you have to disable autoRun:
var app = new EmberApp({
autoRun: false
});
To manually run Ember: require("app-name/app")["default"].create({/* app settings */});
I know that people in production build the cli app into their '/dist' directory, and then server up the 'index' on their server, but I am not sure if this is the right path to go for development.
To recap, I have an ember-cli app that is getting proxied to my node server. I have a '/', '/signIn', and a '/signUp' route that is handled by node.js completely. I also have an ember app that is served at '/app/' and is making requests to my node app successfully.
What I am unsure of is how to server up the ember app once a user is verified at '/signUp' of my node server.
Any help at all is greatly appreciated. I am very new to this stuff, so please be gentle. I have researched this for two business days while consulting with senior engineers, and they have no clue about frameworks such as Ember.

Confusion about web-application ports

I have a project that is already deep in development, and there is a problem with the ports.
The Client is SPA written in backbone, that uses Sails as a server.
Problem is in the fact that Client is running in Express on port 80, while Sails is run on 1337.
I would like to host this backbone application within the Sails, not ouside the sails.
A bit more details:
When I fire the Fiddler, I am seeing requests being made to localhost:1337/get/user.
I need it to reside on port 80 as well.
Backbone is written using standard. I have app.js and main.js with all of the common folders (JS, LIBS, CSS). In other words, I have index.html that has data-main using require.js...
I have not problems running the client in separate node.js... how to run it within Sails.js?
Where do I put my index.html???
Trying to serve index.html as a static file won't work. Instead, try the following:
1. Serve your index.html from Sails
Just serve index.html as a combination of views/layout.ejs and views/home/index.ejs, which are mounted to the root / for default newly created Sails project.
2. Set up a catch-all route
In config/routes.js put something like this:
module.exports.routes = {
'/': {
view: 'home/index'
},
'/:unknownRoute': {
view: 'home/index'
}
}
This way you'll be able, for example, to use simple one-level pushstate routing within your SPA: routes like /products or /news will still give you your index.html (if you are using something more complex though, you may want to play a little bit more with your Sails routes).
3. Serve your API with a prefix
In your config/controllers.js put, for example:
module.exports.controllers = {
...
prefix: '/api',
...
}
This will let you serve your API with a prefix and have both /api/products (JSON API) and /products (your SPA) routes available.
4. Use any port you want
You can change the default port via config/local.js, even to 80 (if you don't have anything else running on 80, of course).
In production though, it would probably be a better idea to just proxy to default Sails' or any other port with Nginx, for example.

Categories