How to ssr Svelte and pass data from express in node js - node.js

I am trying svelte and I might use it for my future website, but there is on thing that has stopped me from suing many js frameworks/compilers. It is server side rendering (one reason is I use server-less so it would be easier then prerendering). Is there a way to use express to server-side-render svelte on every request and also pass data from my node js app too so I don't have to make a bunch of other request? For example the App.svelte might be:
<script>
export let data
let count = 0
</script>
<main>
<button on:click={count++}>Increase Count BY 1</button>
<h1>{data}<h1>
</main>
and main.js:
import App from './App.svelte';
const app = new App({
target: document.body,
props: {
}
});
export default app;
I want to get the data value from the server and use it in the svelte code and also sever-side-render it. Is there a way I can do this?

Related

Use React to build parts of the application features

Consider having a web application that is based on a complex platform, however, you can design HTML Forms using its designer, and insert standard HTML elements, one of which is HTML Component. You can use this component to add HTLM/JavaScript code as usual.
I followed a tutorial to create a react app without using create-react-app. I managed to develop a sample React app using NodeJs, Babel, and Webpack and managed to deploy the final bundled JavaScript main.js on the target application. All worked fine. Below are the main two files with the source code:
index.js
import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
ReactDOM.render(<App />, document.querySelector("#root"));
App.js
import React, {useState} from "react";
const App = () => {
let [counter, setCounter] = useState(0);
const increment = () => {
counter++;
setCounter(counter);
}
return <div>This was created from React and Hello World!
<h1>This is a test Header</h1>
<button onClick={increment}>Click here to increment</button>
<br/>
<span>{counter}</span>
</div>
}
export default App;
The Form HTML Component in the Target Web Application:
<div id="root">This Text should be replaced by the React App</div>
<script src="./target/app/path/public/main.js"></script>
Mind you that I ran the command npm run build and it generated the final script main.js which is deployed to the target application.
I am planning to start using React to build specific components for example a combination of Drop-Down Fields and Grid elements which are populated using REST APIs.
The problem is that I have to have one entry JavaScript source file that will render the component using ReactDOM.render(<App />, document.querySelector("#root")), and if I develop say 100 components, but not all of them will be rendered when any Application Form is loaded. I think if the React render() function is invoked and the target DOM element is not present, then it will throw an error (I am not sure though).
So the question is how to design the application so that I can follow the above approach and ensure that the intended React Component will kick in only when the related Form is loaded or active.
I am thinking to import all the Components in index.js and develop a method to detect if the Form is active and needs a component, then it will invoke the function ReactDOM.render(<MyComponent />, document.querySelector("#MyComponentId")).
I am not sure how to implement that and I need help. I appreciate your feedback.

How to pass config variables from server (Express) to React App

I am building React + Express app and I need to pass some config variables from server config into React App (for example API URL).
I need to do so in development (2 servers - Webpack Dev server + Node.js) and also in production (Only Node.js Express server with built frontend).
How to achieve this?
I tried to pass locals from Express to my template where I did window.config = '<%- JSON.stringify(config) %>' (EJS template system) and then used window.config in React App. I does not think this is right approach.
React is client side and no one will suggest you to pass your server config variables like api keys to client side but if you want to pass the config variables to client side.
You can make do it as
// import config variable to express app.js server side
const config = require('./config.js');
// send the config variable
app.get('/getconfig', (req, res) => {
res.json(config);
});
In the client side make axios get request to /getconfig in actions creator file
export function getConfig() {
const req = axios.get('/getconfig')
.then(res=> res.data)
.catch(err => console.log(err));
return {
type: "GETCONFIG",
payload: req
}
}
Now you can add it to reducers switch case and then use it in any react component.
You can consider to use DefinePlugin in webpack. This feature allow you to create global constants being used in the front-end logic. And as it is created at compile time, you can retrieve the config from Node layer.
For example, you have 2 GTM containers, one for development, another for production. And in the production webpack config, we can use some like this:
const config = require('./node/config/prod.js');
module.exports = {
// skip other setting...
plugins: [
new webpack.DefinePlugin({
'process.env.NODE_ENV' : JSON.stringify('production'),
'process.env.GTM_ID' : JSON.stringify(config.gtm.id)
});
]
};
Then in the html you can use process.env.GTM_ID to dynamically get the GTM id among the different environments.

React router 4 - Link to page outside react app

I'm building a node + react app that uses passport's facebook authentication. Getting this authentication to work involves hitting an express route '/auth/facebook'. Unfortunately as soon as the react app loads up react router 4 doesn't allow links to directly hit the express server and instead searches for a react route matching 'auth/facebook'. In short how do I link to a route within my application but outside of the react app when using react router 4?
React Router is only for client side routing. Use fetch API or a similar library for that.
I'll state one way of solving your problem (using fetch and without react router).
Remove the href from the <a> tag
Add an event listener for the click event, <a onClick={makeCall}>
Then in the makeCall function, you can call the backend using the fetch API(or axios or whatever),
makeCall() {
fetch('/auth/facebook', options)
.then((res) => {
// Something
})
.catch((err) => {
// handle error
});
}

Are you able to use vue.js inside an ejs file?

Sorry guys I am new to node.js and was wondering whether we are allowed to use vue.js within an ejs file.
Yes, we can. Here is a scenario. Let's say you want to render a data Object to ejs file, and you want this data Object be accessible from VueJS.
First, in your controller, you have to render it as a JSON string
res.render("index", { data: JSON.stringify(data) }); in order to access it in your javascript code.
Then, in your VueJS code inside ejs file, you simply access it this way:
var app = new Vue({
el: '#app',
data: {
myData: JSON.parse('<%- data %>')
}
})
Note about <%- tag in your VueJS code, it is necessary in order to output your data properly.
As VueJS can be implemented into existing systems, you should be able to do so yes.

Running a node.js file from a click event

I am new to node.js. I am connecting with an api with express/node.js with ejs templating. I wanted to push some information from the browser to the api. At the moment, I can push from the command line. I understand I cannot call a node.js file from the browser directly but I was wondering when I click submit on a form if it can call node.js file and run it...what should I use, modules, routes, ajax, or any other solutions you recommend? I appreciate the help.
Well, it's a strange question. Your Node application needs to either listen for HTTP requests or WebSocket connections (possibly using some abstraction like Socket.io that can provide fallbacks where WebSocket is not available) and handle the requests or messages sent on the socket. In those handlers you can do whatever you need. This is just a basic principle of client/server architecture.
Now, to choose what technology is best suited for your needs it all depends on how often you need to make that communication, whether or not you need realtime communication, how much data do you need to pass around, if you need to support serving data initiated by the server or only by the client etc.
To answer you question - yes, you can submit a form and make it execute some code in your Node application. This is exactly how forms work - they make a connection, usually GET with data in the query string or POST with data in the body (both can easily be read by Node) and then your handler on the backend handles the request, does whatever it needs and sends a response.
Consider this simple example using express and body-parser:
const app = require('express')();
const { urlencoded } = require('body-parser');
app.use(urlencoded({ extended: true }));
app.use('/', (req, res) => {
const { method, path } = req;
const { x } = req.body;
console.log(`Client request: ${method} ${path} (x = ${x})`);
res.end(`
<!doctype html>
<html>
<head>
<title>Form handling example</title>
</head>
<body>
<p>x = ${x}</p>
<form method="POST" action="/">
Enter x: <input type="text" name="x">
<input type="submit" value="Submit">
</form>
</body>
</html>
`);
});
app.listen(4447, () => console.log('Listening on http://localhost:4447/'));
Create a new directory, save this code as server.js, run:
npm init -y
npm install express body-parser -S
node server.js
and access the printed URL in the browser.
When you click the submit button you'll see what will happen in the Node app.
Your node app will have a route set up which accepts GET or POST requests. Then it does some logic and returns some data in a response.
Your web page will send the form to your node route as GET or POST via an AJAX call, and likewise it will receive a response from the AJAX call. Then you can take this response and use it locally in the webpage however you like.

Resources