ReactJS: "Uncaught SyntaxError: Unexpected token <" - javascript

I am trying to get started building a site in ReactJS. However, when I tried to put my JS in a separate file, I started getting this error: "Uncaught SyntaxError: Unexpected token <".
I tried adding /** #jsx React.DOM */ to the top of the JS file, but it didn't fix anything. Below are the HTML and JS files. Any ideas as to what is going wrong?
HTML
<html>
<head>
<title>Page</title>
<script src="http://fb.me/react-0.12.2.js"></script>
<script src="http://fb.me/JSXTransformer-0.12.2.js"></script>
<script src="http://code.jquery.com/jquery-1.10.0.min.js"> </script>
<script src="./lander.js"> </script>
</head>
<body>
<div id="content"></div>
<script type="text/jsx">
React.render(
<Lander />,
document.getElementById('content')
);
</script>
</body>
</html>
JS
/**
* #jsx React.DOM
*/
var Lander = React.createClass({
render: function () {
var info = "Lorem ipsum dolor sit amet... ";
return(
<div>
<div className="info">{info}</div>
</div>
);
}
});
EDIT: I realized that I need to add type="text/jsx" to the script tag which includes my lander code. However, after adding this and reloading I get this warning
"You are using the in-browser JSX transformer. Be sure to precompile your JSX for production - http://facebook.github.io/react/docs/tooling-integration.html#jsx"
followed by this error:
"XMLHttpRequest cannot load file:///Users/.../lander.js. Cross origin requests are only supported for protocol schemes: http, data, chrome-extension, https, chrome-extension-resource."
it seems like there is something else that I need to do in order to get in browser jsx transform working, but I'm not sure what it is.
EDIT: OOOOH do I need to host it using MAMP or something?

UPDATE --
use this instead:
<script type="text/babel" src="./lander.js"></script>
Add type="text/jsx" as an attribute of the script tag used to include the JavaScript file that must be transformed by JSX Transformer, like that:
<script type="text/jsx" src="./lander.js"></script>
Then you can use MAMP or some other service to host the page on localhost so that all of the inclusions work, as discussed here.
Thanks for all the help everyone!

JSTransform is deprecated , please use babel instead.
<script type="text/babel" src="./lander.js"></script>

Add type="text/babel" as an attribute of the script tag, like this:
<script type="text/babel" src="./lander.js"></script>

Add type="text/babel" to the script that includes the .jsx file and add this: <script src="https://npmcdn.com/babel-core#5.8.38/browser.min.js"></script>

If you have something like
Uncaught SyntaxError: embedded: Unexpected token
You probably missed a comma in a place like this:
var CommentForm = React.createClass({
getInitialState: function() {
return {author: '', text: ''};
}, // <---- DON'T FORGET THE COMMA
render: function() {
return (
<form className="commentForm">
<input type="text" placeholder="Nombre" />
<input type="text" placeholder="Qué opina" />
<input type="submit" value="Publicar" />
</form>
)
}
});

If you are getting an error like this :
SyntaxError: embedded: Unexpected token (107:9) 105
It could be you are missing a curly bracket

The code you have is correct. JSX code needs to be compiled to JS:
http://facebook.github.io/react/jsx-compiler.html

In my case, using src="./<file>.js" didn't work. Using %PUBLIC_URL% did the trick.
<script defer async src="%PUBLIC_URL%/some-file.js"></script>

Try adding in webpack, it solved the similar issue in my project. Specially the "presets" part.
module: {
loaders: [
{
test: /\.jsx?/,
include: APP_DIR,
loader: 'babel',
query :{
presets:['react','es2015']
}
},

In my case, using src="./<file>.js" didn't work. Using `%PUBLIC_URL%

I have the same issue with you and I have change something in my server
you might try this
const root = require("path").join(__dirname, "./build");
app.use(express.static(root));
app.get("*", (req, res) => {
res.sendFile("index.html", { root });
});

In addition to Dee Jee solution, After trying out his solution, My error never went.
I noticed(after two days of head scratch) that the browser has cached the files improperly.
My browser wasn't able to load the preview of the cached files and status code from express was 301.
In the networks tab of the browser dev tools, I get that those files are server from disk cache.
Solution
Remove the cached files. By clearing the browser history in a span of 1 hour, so that all the cached files get deleted.

Related

I got this error in a simple React projec using only CDNs [duplicate]

I am trying to get started building a site in ReactJS. However, when I tried to put my JS in a separate file, I started getting this error: "Uncaught SyntaxError: Unexpected token <".
I tried adding /** #jsx React.DOM */ to the top of the JS file, but it didn't fix anything. Below are the HTML and JS files. Any ideas as to what is going wrong?
HTML
<html>
<head>
<title>Page</title>
<script src="http://fb.me/react-0.12.2.js"></script>
<script src="http://fb.me/JSXTransformer-0.12.2.js"></script>
<script src="http://code.jquery.com/jquery-1.10.0.min.js"> </script>
<script src="./lander.js"> </script>
</head>
<body>
<div id="content"></div>
<script type="text/jsx">
React.render(
<Lander />,
document.getElementById('content')
);
</script>
</body>
</html>
JS
/**
* #jsx React.DOM
*/
var Lander = React.createClass({
render: function () {
var info = "Lorem ipsum dolor sit amet... ";
return(
<div>
<div className="info">{info}</div>
</div>
);
}
});
EDIT: I realized that I need to add type="text/jsx" to the script tag which includes my lander code. However, after adding this and reloading I get this warning
"You are using the in-browser JSX transformer. Be sure to precompile your JSX for production - http://facebook.github.io/react/docs/tooling-integration.html#jsx"
followed by this error:
"XMLHttpRequest cannot load file:///Users/.../lander.js. Cross origin requests are only supported for protocol schemes: http, data, chrome-extension, https, chrome-extension-resource."
it seems like there is something else that I need to do in order to get in browser jsx transform working, but I'm not sure what it is.
EDIT: OOOOH do I need to host it using MAMP or something?
UPDATE --
use this instead:
<script type="text/babel" src="./lander.js"></script>
Add type="text/jsx" as an attribute of the script tag used to include the JavaScript file that must be transformed by JSX Transformer, like that:
<script type="text/jsx" src="./lander.js"></script>
Then you can use MAMP or some other service to host the page on localhost so that all of the inclusions work, as discussed here.
Thanks for all the help everyone!
JSTransform is deprecated , please use babel instead.
<script type="text/babel" src="./lander.js"></script>
Add type="text/babel" as an attribute of the script tag, like this:
<script type="text/babel" src="./lander.js"></script>
Add type="text/babel" to the script that includes the .jsx file and add this: <script src="https://npmcdn.com/babel-core#5.8.38/browser.min.js"></script>
If you have something like
Uncaught SyntaxError: embedded: Unexpected token
You probably missed a comma in a place like this:
var CommentForm = React.createClass({
getInitialState: function() {
return {author: '', text: ''};
}, // <---- DON'T FORGET THE COMMA
render: function() {
return (
<form className="commentForm">
<input type="text" placeholder="Nombre" />
<input type="text" placeholder="Qué opina" />
<input type="submit" value="Publicar" />
</form>
)
}
});
If you are getting an error like this :
SyntaxError: embedded: Unexpected token (107:9) 105
It could be you are missing a curly bracket
The code you have is correct. JSX code needs to be compiled to JS:
http://facebook.github.io/react/jsx-compiler.html
In my case, using src="./<file>.js" didn't work. Using %PUBLIC_URL% did the trick.
<script defer async src="%PUBLIC_URL%/some-file.js"></script>
Try adding in webpack, it solved the similar issue in my project. Specially the "presets" part.
module: {
loaders: [
{
test: /\.jsx?/,
include: APP_DIR,
loader: 'babel',
query :{
presets:['react','es2015']
}
},
In my case, using src="./<file>.js" didn't work. Using `%PUBLIC_URL%
I have the same issue with you and I have change something in my server
you might try this
const root = require("path").join(__dirname, "./build");
app.use(express.static(root));
app.get("*", (req, res) => {
res.sendFile("index.html", { root });
});
In addition to Dee Jee solution, After trying out his solution, My error never went.
I noticed(after two days of head scratch) that the browser has cached the files improperly.
My browser wasn't able to load the preview of the cached files and status code from express was 301.
In the networks tab of the browser dev tools, I get that those files are server from disk cache.
Solution
Remove the cached files. By clearing the browser history in a span of 1 hour, so that all the cached files get deleted.

React with Babel without Node

I'm creating a React application without having to use npm or yarn, just want it to work by opening page.html file.
I have this code in both files, cockpit.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<link href="https://raw.githubusercontent.com/cockpit-project/cockpit/master/src/base1/cockpit.css" type="text/plain" rel="stylesheet">
<script src="https://raw.githubusercontent.com/cockpit-project/cockpit/master/src/base1/cockpit.js" type="text/plain"></script>
<script src="https://unpkg.com/react#16/umd/react.development.js" type="text/plain" crossorigin></script>
<script src="https://unpkg.com/react-dom#16/umd/react-dom.development.js" type="text/plain" crossorigin></script>
<script src="https://unpkg.com/babel-standalone#6/babel.min.js" type="text/jsx"></script>
<title>Cockpit Test</title>
</head>
<body>
<div id="root"></div>
<script type="text/babel" src="cockpitTest.jsx"></script>
</body>
</html>
and cockpitTest.jsx:
"use strict";
const rootElement = document.getElementById('root')
class CockpitTest extends React.Component {
componentDidMount() {
console.log("asd")
}
render() {
return (
<div>
<h1>test</h1>
</div>
);
}
}
function App(){
return(
<div>
<CockpitTest name="Test"/>
</div>
)
}
ReactDOM.render(<App />, document.getElementById('rootElement'))
but still I'm getting a blank screen when h1 text is expected. Console doesn't say anything either, it's just blank. Any help would be appreciated!
You have lots of problems
Content-Type
You've set type attributes on all your script and link elements to tell the browser that the CSS and scripts are in formats it doesn't understand. Don't do that.
Only the JSX file itself (in your last <script>) should have a type attribute.
Github is not a hosting service
You are trying to host the cockpit files on raw.github.com. This is not designed to be used as a CDN and returns data with the wrong Content-Type header. Use a real hosting service.
URL
You named the file cockpit.jsx but said src="cockpitTest.jsx"
Missing element
You said document.getElementById('rootElement') but also id="root". These do not match.
You are working without Node.js
The developer tools for React use Node.js to compile it for production-level performance. There's very little reason to not use them all the way through the development process.
First make it a javascript file .js
Then you can either:
Change:
rootElement = document.querySelector('#root'));
AND:
ReactDOM.render(<App />, rootElement)
OR:
ReactDOM.render(<App />, document.querySelector('#root'))
AND:
Delete your constant.
I even got React Router to work, but had problems when it came to separating components out into files for a tidy structure. Couldn't get imports to work inside app.js. Seems like Babel should have helped with imports and exports, but I couldn't get it to work.
Firstly - on your script type your using type "application/babel". This is not a valid media type, you probably want to use "application/javascript". This could be why nothing is displayed.
Secondly - the script you're using is not valid JS, you're using JSX which browsers cannot understand. JSX is what allows us to write html-like tags in JavaScript (the < /> for example). You would either have to write JS instead of JSX, or transpile your JSX using a transpiler such as babel. I would suggest running a compiler such as babel.
Read more about JSX here.

ReactDOM Uncaught SyntaxError: Unexpected token <

I'm sorry to ask such a specific question but I'm working on a simple tutorial which introduces React with the following HTML
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Hello Separate</title>
</script>
</head>
<body>
<h1>Hello Separate</h1>
<div id="app"></div>
</body>
</html>
And a script to create a <p> within the div id ="app" using ReactDOM
ReactDOM.render(
<p>Rendered by React</p>,
document.getElementById("app")
)
I've provided the code in a fiddle here:
I don't understand why I'm getting the error Uncaught SyntaxError: Unexpected token < but think it's coming from the ReactDOM.render function, can anyone provide insight? Thank you!
Two issues with your code,
First
Your scripts are not proper. As per docs, you should add these scripts,
<script src="https://unpkg.com/react#16/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom#16/umd/react-dom.development.js" crossorigin></script>
<script src="https://unpkg.com/babel-standalone#6/babel.min.js"></script>
Second
Might be you are writing your JS code in external JS file.
From the docs,
Now you can use JSX in any <script> tag by adding type="text/babel" attribute to it.
You need to add this script in your HTML file only,
<script type="text/babel">
ReactDOM.render(
<p>Rendered by React</p>,
document.getElementById("app")
)
</script>
Demo
As Emile Bergeron mentioned you're actually writing JSX, so you need 'build'
or transpile the code in regular JavaScript.
However if you're using just JSFiddle, they can transpile the code for you like this.
If you're working locally you can look into create-react-app as they mentioned or babel and webpack to build/bundle your files.
yes you might be right, you will might need to change: <p>Rendered by React</p> to either '<p>Rendered by React</p>' or "<p>Rendered by React</p>"
like this:
ReactDOM.render(
"<p>Rendered by React</p>",
document.getElementById("app")
)
you have to always enclose text or html in ".."

React Error: Target Container is not a DOM Element

I just got started using React, so this is probably a very simple mistake, but here we go. My html code is very simple:
<!-- base.html -->
<html>
<head>
<title>Note Cards</title>
<script src="http://<url>/react-0.11.2.js"></script>
<!-- <script src="http://<url>/JSXTransformer-0.11.2.js"></script> -->
<script src="http://code.jquery.com/jquery-1.10.0.min.js"></script>
{% load staticfiles %}
<link rel="stylesheet" type="text/css" href="{% static "css/style.css" %}">
<script src="{% static "build/react.js" %}"></script>
</head>
<body>
<h1 id="content">Note Cards</h1>
<div class="gotcha"></div>
</body>
</html>
Note that I am using Django's load static files here. (My JavaScript is a bit more complex, so I won't post it all here unless someone requests it.) This is the line with the error:
React.renderComponent(
CardBox({url: "/cards/?format=json", pollInterval: 2000}),
document.getElementById("content")
);
After which I get the 'target container is not a DOM element error' yet it seems that document.getElementById("content") is almost certainly a DOM element.
I looked at this stackoverflow post, but it didn't seem to help in my situation.
Anyone have any idea why I'd be getting that error?
I figured it out!
After reading this blog post I realized that the placement of this line:
<script src="{% static "build/react.js" %}"></script>
was wrong. That line needs to be the last line in the <body> section, right before the </body> tag. Moving the line down solves the problem.
My explanation for this is that react was looking for the id in between the <head> tags, instead of in the <body> tags. Because of this it couldn't find the content id, and thus it wasn't a real DOM element.
Also make sure id set in index.html is same as the one you referring to in index.js
index.html:
<body>
<div id="root"></div>
<script src="/bundle.js"></script>
</body>
index.js:
ReactDOM.render(<App/>,document.getElementById('root'));
webpack solution
If you got this error while working in React with webpack and HMR.
You need to create template index.html and save it in src folder:
<html>
<body>
<div id="root"></div>
</body>
</html>
Now when we have template with id="root" we need to tell webpack to generate index.html which will mirror our index.html file.
To do that:
plugins: [
new HtmlWebpackPlugin({
title: "Application name",
template: './src/index.html'
})
],
template property will tell webpack how to build index.html file.
Just to give an alternative solution, because it isn't mentioned.
It's perfectly fine to use the HTML attribute defer here. So when loading the DOM, a regular <script> will load when the DOM hits the script. But if we use defer, then the DOM and the script will load in parallel. The cool thing is the script gets evaluated in the end - when the DOM has loaded (source).
<script src="{% static "build/react.js" %}" defer></script>
Also, the best practice of moving your <script></script> to the bottom of the html file fixes this too.
I had encountered the same error with React version 16. This error comes when the Javascript that tries to render the React component is included before the static parent dom element in the html. Fix is same as the accepted answer, i.e. the JavaScript should get included only after the static parent dom element has been defined in the html.
For those that implemented react js in some part of the website and encounter this issue.
Just add a condition to check if the element exist on that page before you render the react component.
<div id="element"></div>
...
const someElement = document.getElementById("element")
if(someElement) {
ReactDOM.render(<Yourcomponent />, someElement)
}
Also you can do something like that:
document.addEventListener("DOMContentLoaded", function(event) {
React.renderComponent(
CardBox({url: "/cards/?format=json", pollInterval: 2000}),
document.getElementById("content")
);
})
The DOMContentLoaded event fires when the initial HTML document has been completely loaded and parsed, without waiting for stylesheets, images, and subframes to finish loading.
One of the case I encountered the same error in a simple project. I hope the solution helps someone.
Below code snippets are sufficient to understand the solution :
index.html
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
</body>
someFile.js : Notice the line const portalElement = document.getElementById("overlays"); below :
const portalElement = document.getElementById("overlays");
const Modal = (props) => {
return (
<Fragment>
      {ReactDOM.createPortal(<Backdrop />, portalElement)}
      
{ReactDOM.createPortal(
<ModalOverlay>{props.children}</ModalOverlay>,
portalElement
)}
    
</Fragment>
);
};
I didn't have any element with id = "overlays" in my index.html file, so the highlighted line above was outputting null and so React wasn't able to find inside which element it should create the portal i.e {ReactDOM.createPortal(<Backdrop />, portalElement)} so I got below error
I added the div in index.html file and the error was gone.
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="overlays"></div>
<div id="root"></div>
</body>
I got the same error i created the app with create-react-app but in /public/index.html also added matrialize script but there was to connection with "root" so i added
<div id="root"></div>
just before
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/ materialize.min.js"></script>
And it worked for me .
Target container is not a DOM element.
I achieved this error with a simple starter app also.
// index.js
ReactDOM.render(
<Router>
<App />,
document.getElementById('root')
</Router>
);
Solution:
Syntax errors can cause this error. I checked my syntax and wrapped my <App /> properly.
ReactDOM.render(
<Router>
<App />
</Router>,
document.getElementById('root')
);
In my case, I forget to add this line to the index.js file
document.getElementById('root')
and I forget to import react-dom import ReactDOM from 'react-dom'; so you can use ReactDOM later in the same file
Hope this will be helpful for you

Include another HTML file in a HTML file

I have 2 HTML files, suppose a.html and b.html. In a.html I want to include b.html.
In JSF I can do it like that:
<ui:include src="b.xhtml" />
It means that inside a.xhtml file, I can include b.xhtml.
How can we do it in *.html file?
In my opinion the best solution uses jQuery:
a.html:
<html>
<head>
<script src="jquery.js"></script>
<script>
$(function(){
$("#includedContent").load("b.html");
});
</script>
</head>
<body>
<div id="includedContent"></div>
</body>
</html>
b.html:
<p>This is my include file</p>
This method is a simple and clean solution to my problem.
The jQuery .load() documentation is here.
Expanding lolo's answer, here is a little more automation if you have to include a lot of files. Use this JS code:
$(function () {
var includes = $('[data-include]')
$.each(includes, function () {
var file = 'views/' + $(this).data('include') + '.html'
$(this).load(file)
})
})
And then to include something in the html:
<div data-include="header"></div>
<div data-include="footer"></div>
Which would include the file views/header.html and views/footer.html.
My solution is similar to the one of lolo above. However, I insert the HTML code via JavaScript's document.write instead of using jQuery:
a.html:
<html>
<body>
<h1>Put your HTML content before insertion of b.js.</h1>
...
<script src="b.js"></script>
...
<p>And whatever content you want afterwards.</p>
</body>
</html>
b.js:
document.write('\
\
<h1>Add your HTML code here</h1>\
\
<p>Notice however, that you have to escape LF's with a '\', just like\
demonstrated in this code listing.\
</p>\
\
');
The reason for me against using jQuery is that jQuery.js is ~90kb in size, and I want to keep the amount of data to load as small as possible.
In order to get the properly escaped JavaScript file without much work, you can use the following sed command:
sed 's/\\/\\\\/g;s/^.*$/&\\/g;s/'\''/\\'\''/g' b.html > escapedB.html
Or just use the following handy bash script published as a Gist on Github, that automates all necessary work, converting b.html to b.js:
https://gist.github.com/Tafkadasoh/334881e18cbb7fc2a5c033bfa03f6ee6
Credits to Greg Minshall for the improved sed command that also escapes back slashes and single quotes, which my original sed command did not consider.
Alternatively for browsers that support template literals the following also works:
b.js:
document.write(`
<h1>Add your HTML code here</h1>
<p>Notice, you do not have to escape LF's with a '\',
like demonstrated in the above code listing.
</p>
`);
Checkout HTML5 imports via Html5rocks tutorial
and at polymer-project
For example:
<head>
<link rel="import" href="/path/to/imports/stuff.html">
</head>
Shameless plug of a library that I wrote the solve this.
https://github.com/LexmarkWeb/csi.js
<div data-include="/path/to/include.html"></div>
The above will take the contents of /path/to/include.html and replace the div with it.
No need for scripts. No need to do any fancy stuff server-side (tho that would probably be a better option)
<iframe src="/path/to/file.html" seamless></iframe>
Since old browsers don't support seamless, you should add some css to fix it:
iframe[seamless] {
border: none;
}
Keep in mind that for browsers that don't support seamless, if you click a link in the iframe it will make the frame go to that url, not the whole window. A way to get around that is to have all links have target="_parent", tho the browser support is "good enough".
A simple server side include directive to include another file found in the same folder looks like this:
<!--#include virtual="a.html" -->
Also you can try:
<!--#include file="a.html" -->
A very old solution I did met my needs back then, but here's how to do it standards-compliant code:
<!--[if IE]>
<object classid="clsid:25336920-03F9-11CF-8FD0-00AA00686F13" data="some.html">
<p>backup content</p>
</object>
<![endif]-->
<!--[if !IE]> <-->
<object type="text/html" data="some.html">
<p>backup content</p>
</object>
<!--> <![endif]-->
Following works if html content from some file needs to be included:
For instance, the following line will include the contents of piece_to_include.html at the location where the OBJECT definition occurs.
...text before...
<OBJECT data="file_to_include.html">
Warning: file_to_include.html could not be included.
</OBJECT>
...text after...
Reference: http://www.w3.org/TR/WD-html40-970708/struct/includes.html#h-7.7.4
Here is my inline solution:
(() => {
const includes = document.getElementsByTagName('include');
[].forEach.call(includes, i => {
let filePath = i.getAttribute('src');
fetch(filePath).then(file => {
file.text().then(content => {
i.insertAdjacentHTML('afterend', content);
i.remove();
});
});
});
})();
<p>FOO</p>
<include src="a.html">Loading...</include>
<p>BAR</p>
<include src="b.html">Loading...</include>
<p>TEE</p>
In w3.js include works like this:
<body>
<div w3-include-HTML="h1.html"></div>
<div w3-include-HTML="content.html"></div>
<script>w3.includeHTML();</script>
</body>
For proper description look into this: https://www.w3schools.com/howto/howto_html_include.asp
As an alternative, if you have access to the .htaccess file on your server, you can add a simple directive that will allow php to be interpreted on files ending in .html extension.
RemoveHandler .html
AddType application/x-httpd-php .php .html
Now you can use a simple php script to include other files such as:
<?php include('b.html'); ?>
This is what helped me. For adding a block of html code from b.html to a.html, this should go into the head tag of a.html:
<script src="https://code.jquery.com/jquery-1.10.2.js"></script>
Then in the body tag, a container is made with an unique id and a javascript block to load the b.html into the container, as follows:
<div id="b-placeholder">
</div>
<script>
$(function(){
$("#b-placeholder").load("b.html");
});
</script>
I know this is a very old post, so some methods were not available back then.
But here is my very simple take on it (based on Lolo's answer).
It relies on the HTML5 data-* attributes and therefore is very generic in that is uses jQuery's for-each function to get every .class matching "load-html" and uses its respective 'data-source' attribute to load the content:
<div class="container-fluid">
<div class="load-html" id="NavigationMenu" data-source="header.html"></div>
<div class="load-html" id="MainBody" data-source="body.html"></div>
<div class="load-html" id="Footer" data-source="footer.html"></div>
</div>
<script src="js/jquery.min.js"></script>
<script>
$(function () {
$(".load-html").each(function () {
$(this).load(this.dataset.source);
});
});
</script>
Most of the solutions works but they have issue with jquery:
The issue is following code $(document).ready(function () { alert($("#includedContent").text()); } alerts nothing instead of alerting included content.
I write the below code, in my solution you can access to included content in $(document).ready function:
(The key is loading included content synchronously).
index.htm:
<html>
<head>
<script src="jquery.js"></script>
<script>
(function ($) {
$.include = function (url) {
$.ajax({
url: url,
async: false,
success: function (result) {
document.write(result);
}
});
};
}(jQuery));
</script>
<script>
$(document).ready(function () {
alert($("#test").text());
});
</script>
</head>
<body>
<script>$.include("include.inc");</script>
</body>
</html>
include.inc:
<div id="test">
There is no issue between this solution and jquery.
</div>
jquery include plugin on github
You can use a polyfill of HTML Imports (https://www.html5rocks.com/en/tutorials/webcomponents/imports/), or that simplified solution
https://github.com/dsheiko/html-import
For example, on the page you import HTML block like that:
<link rel="html-import" href="./some-path/block.html" >
The block may have imports of its own:
<link rel="html-import" href="./some-other-path/other-block.html" >
The importer replaces the directive with the loaded HTML pretty much like SSI
These directives will be served automatically as soon as you load this small JavaScript:
<script async src="./src/html-import.js"></script>
It will process the imports when DOM is ready automatically. Besides, it exposes an API that you can use to run manually, to get logs and so on. Enjoy :)
Here's my approach using Fetch API and async function
<div class="js-component" data-name="header" data-ext="html"></div>
<div class="js-component" data-name="footer" data-ext="html"></div>
<script>
const components = document.querySelectorAll('.js-component')
const loadComponent = async c => {
const { name, ext } = c.dataset
const response = await fetch(`${name}.${ext}`)
const html = await response.text()
c.innerHTML = html
}
[...components].forEach(loadComponent)
</script>
To insert contents of the named file:
<!--#include virtual="filename.htm"-->
Another approach using Fetch API with Promise
<html>
<body>
<div class="root" data-content="partial.html">
<script>
const root = document.querySelector('.root')
const link = root.dataset.content;
fetch(link)
.then(function (response) {
return response.text();
})
.then(function (html) {
root.innerHTML = html;
});
</script>
</body>
</html>
Did you try a iFrame injection?
It injects the iFrame in the document and deletes itself (it is supposed to be then in the HTML DOM)
<iframe src="header.html" onload="this.before((this.contentDocument.body||this.contentDocument).children[0]);this.remove()"></iframe>
Regards
The Athari´s answer (the first!) was too much conclusive! Very Good!
But if you would like to pass the name of the page to be included as URL parameter, this post has a very nice solution to be used combined with:
http://www.jquerybyexample.net/2012/06/get-url-parameters-using-jquery.html
So it becomes something like this:
Your URL:
www.yoursite.com/a.html?p=b.html
The a.html code now becomes:
<html>
<head>
<script src="jquery.js"></script>
<script>
function GetURLParameter(sParam)
{
var sPageURL = window.location.search.substring(1);
var sURLVariables = sPageURL.split('&');
for (var i = 0; i < sURLVariables.length; i++)
{
var sParameterName = sURLVariables[i].split('=');
if (sParameterName[0] == sParam)
{
return sParameterName[1];
}
}
}​
$(function(){
var pinc = GetURLParameter('p');
$("#includedContent").load(pinc);
});
</script>
</head>
<body>
<div id="includedContent"></div>
</body>
</html>
It worked very well for me!
I hope have helped :)
html5rocks.com has a very good tutorial on this stuff, and this might be a little late, but I myself didn't know this existed. w3schools also has a way to do this using their new library called w3.js. The thing is, this requires the use of a web server and and HTTPRequest object. You can't actually load these locally and test them on your machine. What you can do though, is use polyfills provided on the html5rocks link at the top, or follow their tutorial. With a little JS magic, you can do something like this:
var link = document.createElement('link');
if('import' in link){
//Run import code
link.setAttribute('rel','import');
link.setAttribute('href',importPath);
document.getElementsByTagName('head')[0].appendChild(link);
//Create a phantom element to append the import document text to
link = document.querySelector('link[rel="import"]');
var docText = document.createElement('div');
docText.innerHTML = link.import;
element.appendChild(docText.cloneNode(true));
} else {
//Imports aren't supported, so call polyfill
importPolyfill(importPath);
}
This will make the link (Can change to be the wanted link element if already set), set the import (unless you already have it), and then append it. It will then from there take that and parse the file in HTML, and then append it to the desired element under a div. This can all be changed to fit your needs from the appending element to the link you are using. I hope this helped, it may irrelevant now if newer, faster ways have come out without using libraries and frameworks such as jQuery or W3.js.
UPDATE: This will throw an error saying that the local import has been blocked by CORS policy. Might need access to the deep web to be able to use this because of the properties of the deep web. (Meaning no practical use)
Use includeHTML (smallest js-lib: ~150 lines)
Loading HTML parts via HTML tag (pure js)
Supported load: async/sync, any deep recursive includes
Supported protocols: http://, https://, file:///
Supported browsers: IE 9+, FF, Chrome (and may be other)
USAGE:
1.Insert includeHTML into head section (or before body close tag) in HTML file:
<script src="js/includeHTML.js"></script>
2.Anywhere use includeHTML as HTML tag:
<div data-src="header.html"></div>
There is no direct HTML solution for the task for now. Even HTML Imports (which is permanently in draft) will not do the thing, because Import != Include and some JS magic will be required anyway.
I recently wrote a VanillaJS script that is just for inclusion HTML into HTML, without any complications.
Just place in your a.html
<link data-wi-src="b.html" />
<!-- ... and somewhere below is ref to the script ... -->
<script src="wm-html-include.js"> </script>
It is open-source and may give an idea (I hope)
You can do that with JavaScript's library jQuery like this:
HTML:
<div class="banner" title="banner.html"></div>
JS:
$(".banner").each(function(){
var inc=$(this);
$.get(inc.attr("title"), function(data){
inc.replaceWith(data);
});
});
Please note that banner.html should be located under the same domain your other pages are in otherwise your webpages will refuse the banner.html file due to Cross-Origin Resource Sharing policies.
Also, please note that if you load your content with JavaScript, Google will not be able to index it so it's not exactly a good method for SEO reasons.
Web Components
I create following web-component similar to JSF
<ui-include src="b.xhtml"><ui-include>
You can use it as regular html tag inside your pages (after including snippet js code)
customElements.define('ui-include', class extends HTMLElement {
async connectedCallback() {
let src = this.getAttribute('src');
this.innerHTML = await (await fetch(src)).text();;
}
})
ui-include { margin: 20px } /* example CSS */
<ui-include src="https://cors-anywhere.herokuapp.com/https://example.com/index.html"></ui-include>
<div>My page data... - in this snippet styles overlaps...</div>
<ui-include src="https://cors-anywhere.herokuapp.com/https://www.w3.org/index.html"></ui-include>
None of these solutions suit my needs. I was looking for something more PHP-like. This solution is quite easy and efficient, in my opinion.
include.js ->
void function(script) {
const { searchParams } = new URL(script.src);
fetch(searchParams.get('src')).then(r => r.text()).then(content => {
script.outerHTML = content;
});
}(document.currentScript);
index.html ->
<script src="/include.js?src=/header.html">
<main>
Hello World!
</main>
<script src="/include.js?src=/footer.html">
Simple tweaks can be made to create include_once, require, and require_once, which may all be useful depending on what you're doing. Here's a brief example of what that might look like.
include_once ->
var includedCache = includedCache || new Set();
void function(script) {
const { searchParams } = new URL(script.src);
const filePath = searchParams.get('src');
if (!includedCache.has(filePath)) {
fetch(filePath).then(r => r.text()).then(content => {
includedCache.add(filePath);
script.outerHTML = content;
});
}
}(document.currentScript);
Hope it helps!
Here is a great article, You can implement common library and just use below code to import any HTML files in one line.
<head>
<link rel="import" href="warnings.html">
</head>
You can also try Google Polymer
To get Solution working you need to include the file csi.min.js, which you can locate here.
As per the example shown on GitHub, to use this library you must include the file csi.js in your page header, then you need to add the data-include attribute with its value set to the file you want to include, on the container element.
Hide Copy Code
<html>
<head>
<script src="csi.js"></script>
</head>
<body>
<div data-include="Test.html"></div>
</body>
</html>
... hope it helps.
There are several types of answers here, but I never found the oldest tool in the use here:
"And all the other answers didn't work for me."
<html>
<head>
<title>pagetitle</title>
</head>
<frameset rows="*" framespacing="0" border="0" frameborder="no" frameborder="0">
<frame name="includeName" src="yourfileinclude.html" marginwidth="0" marginheight="0" scrolling="no" frameborder="0">
</frameset>
</html>

Categories