I have a component that I want to mount directly to the body but not override the app HTML.
index.html (Basic boilerplate)
<!DOCTYPE html>
<html lang="en">
<body>
<div id="app"></div>
<script type="module" src="/src/main.js"></script>
</body>
</html>
main.js
import { createApp } from "vue";
import App from "./App.vue";
import BodyComponent from "./BodyComponent.vue";
createApp(App).mount("#app");
createApp(BodyComponent).mount("body");
When I do this, it seems like the mount is greedy and it completely wipes out what was previously on the body (example)... I simply want to append the component to the body. I know that in the index.html file I can add a div with an ID that I want to mount my BodyComponent to, but I want to mount it on the body, nothing else. Is this possible?
Related
I am self-learning react and I am just confused about a lot of things.
I thought that if I add React to my index.html via a script like the below:-
//index.html
<!DOCTYPE html>
<html lang="en">
<head>
<title>Bill Details</title>
</head>
<body>
<div id="billTable"></div>
<script src="BillTable.js" type="text/javascript"></script> ------------- Problem Line 1
</script>
</body>
</html>
and this is my js file where I am trying to return react component
//BillTable.js
import React from "react";
import ReactDOM from "react-dom";
function BillTable() {
return <h1>HELLO TABLE</h1>;
}
ReactDOM.render(<BillTable/>, document.getElementById("billTable"));
when I try to open index.html directly in firefox or through express server I get the below error in console:-
Uncaught SyntaxError: import declarations may only appear at top level of a module.
I then got rid of this error by changing the script type in problem line 1 in index.html to
<script src="BillTable.js" type="text/babel"></script>
but then also my webpage is completely blank and even console is not showing any errors.
Please suggest how to solve this issue. I am right now trying to learn React with functional approach only, so if any changes are required to be done on the react side, please make them in the functional approach.
I don't think you have included the correct packages to handle React components and JSX yet. These packages react, react-dom, etc. are usually in a package.json and are required to tell the browser what tools will be used to run the code. These packages handle the "script" or components you create and places the elements constructed in your components to the DOM. You can solve this by loading react with additional script tags before your component's script tag. This will let the browser know how and what to use to run your react component. Also, in your function, it does not know that it is a React Component. Check out an explanation for why you would have to use React.createElement I have attached an example of using only an index.html page here:
example of using an index.html page
Your Component file:
"use strict";
function BillTable() {
return React.createElement("h1", "", "HELLO TABLE");
}
const domContainer = document.querySelector("#billTable");
const root = ReactDOM.createRoot(domContainer);
root.render(React.createElement(BillTable));
and your index.html:
<body>
<div id="billTable"></div>
<!-- Load your React packages -->
<script
src="https://unpkg.com/react#18/umd/react.development.js"
crossorigin
></script>
<script
src="https://unpkg.com/react-dom#18/umd/react-dom.development.js"
crossorigin
></script>
<!-- Load your React component. -->
<script src="BillTable.js"></script>
</body>
How to use setInterval function in react to repeatedly render a function in react . Please provide a very simple example . I am using Node js local environment. Here I am trying for a simple clock given in react documentation (but mine file structure is different). I don't know about didMount etc.. Just starting.
Below is my App.jsx
import React,{ Component } from 'react';
class App extends Component {
good(){
{new Date().toLocaleTimeString()}
}
render() {
return (
<p>{setInterval(()=>this.good(),500)}</p>
);
}
}
export default App;
main.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App.jsx';
ReactDOM.render(<App />, document.getElementById('app'));
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset = "UTF-8">
<title>React App</title>
</head>
<body>
<div id="app"></div>
<script src="index.js"></script>
</body>
</html>
My folder structure is like below
I suggest you to read more about React components, state and props as these are fundamental parts for which you have chosen to use React in first place. Basic steps would be:
Store time as state of your component.
Start ticking functionality as soon as your component loads (that is what componentDidMount does - it's triggered when component loads in page)
On each tick use setState to change time value (setState triggers render)
If you follow these steps you would achieve similar result to example from React site, and this is how it should really be done (if you really want to do it in React design)
I am having trouble loading a Unity file in my React project. I thought if I add the file in index.html I would be able to use UnityLoader anywhere in the project as shown below:
index.html
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Game</title>
</head>
<body>
<div id="app">
</div>
<script src="UnityLoader.js"></script>
</body>
</html>
Unity.js
class Unity extends Component {
render() {
return (
<div id="unity">
{UnityLoader.instantiate('unity', 'unity/index.html')}
</div>
);
}
}
However, I get an error saying UnityLoader is undefined.
Do I need to use some sort of
import { UnityLoader } from 'UnityLoader'
in Unity.js? The issue is that UnityLoader is an external JS file and does not export anything.
Why not installing React-Unity via npm and then import it into your component?
import React, { Component } from 'react';
import { Unity } from 'react-unity-webgl';
export class App extends Component {
render() {
return (<div className="app">
<Unity src="Build/myGame.json" />
</div>)
}
}
Don't forget to add a script tag to load the UnityLoader.js file, exported by Unity in your base html file.
<script src="build_unity/Build/UnityLoader.js"></script>
<script src="compiled/bundle.js"></script>
I have a react app which has an entrypoint of my app.jsx and I am adding segment.io to my build, however I would like to set it's API key as an process.env variable. I am having trouble with how to do this with webpack because my entry point is not the index.html.
I am trying to see if there is a way so I can (on the index.html) do something like this
<script type="text/javascript">
..segment script loading here + (process.env.MY_SEGMENT_KEY)}();
</script>
But I am not sure how to get it so I can process env variables at the index.html level.
In app.jsx I am toggling the code like :
if (process.env.MY_SEGMENT_KEY) {
....
}
and this works fine because I have access to the vars at this point. I would like to also conditionally load the script on the index.html. Anyone know if this is possible? Thanks!
Just load analytics in your JSX file as follow:
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
if (process.env.MY_SEGMENT_KEY) {
window.analytics.load(process.env.MY_SEGMENT_KEY);
}
ReactDOM.render(
<App />,
document.getElementById('root')
);
Your index.html file should look like that:
<!DOCTYPE html>
<html>
<head>
...
<title>My App</title>
<script type="text/javascript">
!function(){var analytics=window.analytics=window.analytics||[];if(!analytics.initialize)if(analytics.invoked)window.console&&console.error&&console.error("Segment snippet included twice.");else{analytics.invoked=!0;analytics.methods=["trackSubmit","trackClick","trackLink","trackForm","pageview","identify","reset","group","track","ready","alias","debug","page","once","off","on"];analytics.factory=function(t){return function(){var e=Array.prototype.slice.call(arguments);e.unshift(t);analytics.push(e);return analytics}};for(var t=0;t<analytics.methods.length;t++){var e=analytics.methods[t];analytics[e]=analytics.factory(e)}analytics.load=function(t){var e=document.createElement("script");e.type="text/javascript";e.async=!0;e.src=("https:"===document.location.protocol?"https://":"http://")+"cdn.segment.com/analytics.js/v1/"+t+"/analytics.min.js";var n=document.getElementsByTagName("script")[0];n.parentNode.insertBefore(e,n)};analytics.SNIPPET_VERSION="4.0.0";
}}();
</script>
</head>
<body>
<div id="root">
</div>
</body>
</html>
I'm having a difficult time importing client side javascript files with flow router. Without flow router, the imports work as expected but the second I introduce flow router the files aren't loaded properly.
Here are what my files look like. Anybody out there ever experienced this ? You help is greatly appreciated! If you help me I will be 100% sure to mark your answer as so :)
client/main.js
import '../imports/startup/client'; // initialize all relevant javascript
import './main.html';
client/main.html
<head>
<title>Welcome </title>
</head>
<template name="visitorLayout">
<body>
{{> Template.dynamic template=header }}
{{> Template.dynamic template=main }}
{{> Template.dynamic template=footer }}
</body>
</template>
<template name="adminLayout">
<body>
{{> Template.dynamic template=main }}
</body>
</template>
imports/startup/client/index.js
import '../../ui/pages/landing_page/modernizr-2.6.2.min.js';
import '../../ui/pages/landing_page/jquery.easing.1.3.js';
import '../../ui/pages/landing_page/bootstrap.min.js';
import '../../ui/pages/landing_page/jquery.waypoints.min.js';
import './routes';
imports/startup/client/routes.js
import { FlowRouter } from 'meteor/kadira:flow-router';
import { BlazeLayout } from 'meteor/kadira:blaze-layout';
FlowRouter.route('/', {
action() {
BlazeLayout.render('visitorLayout', {
header : "header",
footer : "footer",
main : "index"
})
}
});
FlowRouter.route('/admin', {
action() {
BlazeLayout.render('adminLayout', {
main : "admin"
})
}
});
I guess is that you have problem with files loading order. It seems like your routes.js is loaded before main.html therefore there is no template available to render. To fix, try one of the followings:
Remove the line import './main.html'; in client/main.js, files under client folder do not need imported they are loaded automatically.
Create a new html file including the two templates you want to render (visitorLayout and adminLayout) under import folder or sub-folder of import, then import this new html file in routes.js. You also need to remove body tag inside those two templates, use div instead, because body is a special tag in Meteor and are not treated like other tags