Using Static HTML landing page template with Angular 6 application - html

I have an Angular 6 app hosted on say example.com (dist folder being served using say port 5000) and a landing page folder with its HTML, CSS, JS files being served on say port 6000 and hosted on example.com/welcome
Is there any way I can merge these two such that example.com uses landing page static folder and example.com/#/* (Angular app uses hash in routing) uses dist folder?
I do not want to merge landing page into a component in Angular app due to clashing of CSS, and other issues.
I need landing page to be loaded without loading Angular app first and without changing any URL/routing logic of Angular app.
Solutions I tried:
Following code works but loads angular app first and then loads landing page. What I want is that landing page needs to be loaded first.
app.use('/welcome',express.static(__dirname + '/landing'));
app.use(express.static(__dirname + '/dist'));
app.get('/',(req,res)=> {
res.redirect('https://example.com/welcome');
})
I tried to make home component of Angular app redirect to /welcome but that too requires loading of Angular app first before the landing page.
Any solution around Express/Nginx?

I would try to separate angular files and landing page files each in a different directory within the static directory.
app.js:
// serve static files
app.use(express.static(path.join(__dirname, 'public')));
// serve angular app
app.get('*', (req, res, next) => {
// Landing page exception
if (req.originalUrl === '/welcome') {
return next();
}
res.sendFile(path.resolve('public/dist/index.html'));
});
// serve landing page
app.get('/welcome', (req, res) => {
res.sendFile(path.resolve('public/welcome/index.html'));
});
angular router:
if (!window.location.hash && window.location.pathname === '/') {
// redirect the request to GET /welcome
}
public/welcome/index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Landing Page</title>
</head>
<body>
</body>
<!--static files can be accessed at public/welcome/-->
<script type="text/javascript" src="welcome/test.js"></script>
</html>

This answer partly solves the problem. I tried to implement a solution based on the idea given by #mas and it worked. Below is what I changed:
server.js:
app.use('/welcome',express.static(__dirname + '/landing'));
app.use(express.static(__dirname + '/dist'));
Now adding a script in Angular app's root index.html before <app-root> (preferably before the body contents):
angular's index.html:
<script>
if (!window.location.hash && window.location.pathname === '/') {
// redirect the request to GET /welcome
window.location.href = "https://example.com/welcome";
}
</script>
When the browser encounters a script tag when parsing the HTML, it stops parsing and hands over to the Javascript interpreter, which runs the script. The parser doesn't continue until the script execution is complete. Thus, angular's index.html redirects users to landing page before loading the angular app on the user's browser.
This implementation partly solves the problem in the following ways:
Loading of static landing page without loading angular app before it.
No change in the URL/routes of the angular app
It doesn't solve the problem of wanting to load the landing page on same URL i.e. https://example.com and still redirects users to a different path: https://example.com/welcome
Now, if the user hits the domain, it will immediately load the static landing page.

Related

Serve top level domain as static html page in next.js?

In next.js you can use the "public" directory in your root directory to serve static assets. I have my index.html file in this directory because I want my landing page to be purely static.
However, when using next or next start, I cannot access my landing page at http://localhost:3000/. I can only access my landing page at "http://localhost:3000/index.html".
Is there a way to setup next.js, so the top level domain (http://localhost:3000) will serve my landing page?
You can add rewrites to your next.config.js. To allow the url mysite.com/ to point to /public/index.html, I added this to my config (with the content in my /public directory):
rewrites: async () => {
return [
{
source: "/",
destination: "/index.html",
}
]
}
Note: index.jsx/.tsx will take precedence over files in /public
Source: https://nextjs.org/docs/api-reference/next.config.js/rewrites
Next.js router serves only pages exported from .js, .ts and .tsx in pages directory.
You would need a custom server that would serve anything outside of that.
Custom Server
Also, if you use a reverse proxy like nginx you could handle this request by the server before it hits Node.js.
What is the use case of it? If the landing page is just a .html file, you can wrap it in a Next.js page. With server side rendering, the page will be pre-rendered on the server and served the same as it was just a .html file.
Alternatively, if you can't convert HTML to JSX you could use dangerouslySetInnerHTML to set raw HTML code to React's render().
However, beware of cross-site scripting (XSS) attacks.

How do I import an HTML template into a Vue.js project?

I want to import a template that I downloaded off the internet into my vue project. The template has its own HTML, CSS, and Javascript files. How do I use vue-router to access the index.html that is in that project without converting them into vue components?
I'm not sure if v-html is the way to go since I have to import and then convert the HTML into a huge string.
I'm doing this for my landing page so it doesn't need to access Vuex and all the other complexities. I just need it to be displayed as a normal HTML.
Here is my folder structure
What you can do is, serve the landing page off the root of your webapp, and serve vue's dist folder from a subfolder.
For example, your landing is served from abc.com/index.html and your vue app is served from abc.com/app/index.html, and the you can use a simple anchor to send the user to the vue dist folder.
The actionable steps would be -
1. Set vue's dist folder to public/app
2. When finally deploying, set webapp root to public and make sure the index.html inside public is the one of the landing template you downloaded.
So, now, when user will go to /, your downloaded landing will be shown, but when they go to /app, vue's build folder's index.html will be returned, thus taking him to the vue app.

How to render a React component with a express router?

So I have began my project as a React single page application. But it turns out it would be more convenient to have a basic back-end for rendering the pages and have a real routing.
Plus I have some variables that need to be accessible from all pages, and putting them as props to all the components is really heavy. So sending them with the pages could be a solution.
So I added Express, and I can now render a basic HTML page with it.
But I don't know how I am going to link my react component to this html file. Or pass it the needed variables.
I used react-router-dom but it doesn't support page refreshing. And it doesn't help with having global variables needing to be accessible from all components.
Here in my index.js you can see how I render my basic html file, and also at the end and commented, how my react component was rendered before adding express.
app.use(express.static('public'));
router.get('/', function(req, res, next) {
res.sendFile('./public/views/loginView.html' , { root : __dirname});
});
app.use(router);
app.listen('8080');
// const wrapper = document.getElementById("app");
// wrapper ? ReactDOM.render(<App />, wrapper) : false;
Here my loginView.html
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="utf-8">
<!-- links and scripts -->
<title>The login page</title>
</head>
<body>
<div id="app">
content
</div>
</body>
</html>
Is there a simple way to link my html file with its react component and render it ?
If not, is there another way to make some variables (which are not constants) accessible from every react component (maybe react-redux) ?
So with React you want to create a production ready bundle. This normally involves splitting the bundle up so you aren't serving a 5+Mb file to the user to download (using 4G for example with poor connection would take too long) and minifying and uglifying the code (so no one steals your code). These bundled javascript files would then be hosted on your server with reference to them in the HTML file.
The express app would then go along the lines off any route just display the HTML file e.g. router.get('*', (req, res) => res.send('index.html)).
I would recommend using webpack to create the bundle as it helps with the splitting and minifying etc. Take a look at webpack for development and production aswell as create-react-app for quick project setup.

Serving a static page as index.html (so as root page) in Angular 7

I'm facing the following issue:
I have a bought HTML template with some Jquery JS CSS... Which is ok for me as a static page but at the blog section, I'm using angular.
So somehow I want to use that template as the index.html and just run my angular app when the user navigates to that section.
I'm pretty sure that the problem is coming from the routing, but I don't know how to solve it without routing.
I copied my full template to my assets folder, and from the browser, I can run it if I navigate to http://localhost:4200/assets/index.html it loads js Jquery CSS perfectly.
So now:
How can I set to reach this template at just http://localhost:4200/ ?
And then how can I navigate from it to my angular app ?
this is how my routes looks like now:
const routes: Routes = [ { path: "", redirectTo: "/blog", pathMatch: "full"}, { path: "", loadChildren: "./posts/posts.module#PostsModule" }
];

Provide HTML using Node.js and templating to an HTML website

I created a main menu (navigation) using Node.js. I used Jade as the template engine under express. The menu is created in pure HTML & CSS.
Node.js is intended to provide the menu via a URL. I want to include this menu into an existing web application and it should be provided by Node.js. I thought about something like the following in my website.html:
<body>
<!-- begin: include main menu -->
<script type="text/javascript" src="http://127.0.0.1:3000/menu"></script>
<!-- end: include main menu -->
the rest of the application/website
...
</body>
I got it to work pass some HTML to my website using the following code in my routing mechanism, but I think this is really dirty done:
res.send("document.write('SOME_HTML_GOES_HERE')");
But I need to pass the views/menu.jade as HTML snippet back to the website.html. I already returned whole HTML sites with:
res.render('index', { title: 'Express & Jade' });
How can I get that the menu is loaded in a non Node.js application delivered by Node using a template mechanism?
You should rather use an iframe to include the node.js menu. You can include the HTML rendered by Express and Jade:
<iframe src="http://127.0.0.1:3000/menu"></iframe>
That being said, I think you should try to serve all your website from port 80. Many users cannot access port 3000.
If you're hosting your website on node.js (port 3000) and, say, Apache (port 80), you should try to deploy a proxy in front of both of them. I used HAProxy to do this. In my case, the proxy runs on port 80, Apache on 8000 and node.js on 3000. I have simple rules to redirect request to either node.js or Apache.