796

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?

Kamil Kiełczewski
  • 85,173
  • 29
  • 368
  • 345
lolo
  • 17,392
  • 9
  • 25
  • 49
  • 45
    NO! its 2 different things! – lolo Mar 04 '12 at 10:11
  • related, but for `localhost`: http://stackoverflow.com/questions/7542872/how-to-include-one-html-file-into-another – cregox May 12 '15 at 21:21
  • See HTML Modules https://github.com/w3c/webcomponents/blob/gh-pages/proposals/html-modules-explainer.md and https://groups.google.com/a/chromium.org/forum/#!msg/blink-dev/ewfRSdqcOd8/w_Fr6rJ3DQAJ and https://github.com/w3c/webcomponents/blob/gh-pages/proposals/html-module-spec-changes.md and background discussion at https://github.com/w3c/webcomponents/issues/645 and some issue discussion at https://github.com/w3c/webcomponents/issues/783 – sideshowbarker Mar 01 '19 at 10:10
  • I included a navigation element in multiple pages like this: `` But this works just for html-files in the same directory "subdir". The navigation.html cannot be reached from the index.html in the upper main directory "dir". How can I solve this issue? – peng Mar 27 '19 at 17:14
  • refer to this link https://github.com/LexmarkWeb/csi.js . Hope this will help. – Hamza Ali Aug 06 '19 at 06:52
  • Use:
    as explained in https://www.w3schools.com/howto/howto_html_include.asp
    – FrankIJ Dec 17 '19 at 14:57
  • https://css-tricks.com/the-simplest-ways-to-handle-html-includes/ – Gabriel Mar 04 '21 at 15:12
  • I use the solution provided by michael marr here: https://stackoverflow.com/questions/3928331/equivalent-of-include-in-html – Gabriel Mar 04 '21 at 16:58

44 Answers44

813

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.

SharpC
  • 6,974
  • 4
  • 45
  • 40
lolo
  • 17,392
  • 9
  • 25
  • 49
  • 8
    What is the difference of doing just this ` ? – Rodrigo Ruiz Apr 11 '15 at 04:52
  • 20
    @RodrigoRuiz `$(function(){})` will only execute after the document finishes loading. – ProfK May 10 '15 at 16:20
  • Awesome! But how about using `$("div").appendTo('body').load("b.html");` and dropping the whole `div includedContent` instead? Makes it much easier to include many other files! :) – cregox May 12 '15 at 20:46
  • @Cawas, wouldn't that stick `b.html` into every `div`? – Kirby Sep 08 '15 at 22:09
  • Yes it would @Kirby. I meant `$("#includedContent")`, which would make more sense in this context. Thanks for the tip! ;) – cregox Sep 08 '15 at 22:18
  • 10
    If the included HTML file has CSS attached to it, it might mess up your page style. – Omar Jaafor Oct 07 '15 at 14:19
  • 6
    I am exactly like you have mentioned. I am using bootstrap and have css overwrites for B.html. When I use B.html in A.html so that it would end up as A.html's header, I can see that the css has lost its priority and has a different layout. Any solutions to this?. – Pavan Dittakavi Oct 08 '15 at 19:01
  • 1
    Does the file I will include needs to have the ... and other parts? Or can I just have the line of code itself? for example,

    display

    – Jaycee Evangelista Sep 01 '16 at 06:15
  • @Jaycee Evangelista Try both. Not sure what happens if you include `...` -type included files. – parsecer Sep 13 '16 at 16:07
  • 85
    **This does require a server**. When using it on a local file: `XMLHttpRequest cannot load file:///.../b.html. Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https, chrome-extension-resource.` – Basj Dec 04 '16 at 12:02
  • 3
    @Basj you can get around that, for now, by using Firefox instead. I think there is also a chrome add-in available to get around this. More info here: http://stackoverflow.com/questions/20041656/xmlhttprequest-cannot-load-file-cross-origin-requests-are-only-supported-for-ht –  Dec 06 '16 at 15:11
  • @JayceeEvangelista You probably should use a valid complete HTML file if the extension is .html or .htm. You can however, use this method to only load certain elements using $("#result").load( "ajax/test.html #container" ); (in this case, only the container element would be inserted. See http://api.jquery.com/load/#loading-page-fragments for details). – java-addict301 Oct 26 '17 at 15:19
  • If you need to debug your code in Chrome, anything you load dynamically will not show up in DevTools. – Johann Sep 04 '18 at 07:53
  • 1
    @jpaugh please refer to the doc in his answer - it's an other `.load` that has been removed: [Note: Prior to jQuery 3.0, the event handling suite also had a method named .load(). Older versions of jQuery determined which method to fire based on the set of arguments passed to it.](http://api.jquery.com/load/) – inetphantom Sep 22 '18 at 20:56
  • @inetphantom Thanks! I'd forgotten about there being two of them! (I'm so happy they removed it!) – jpaugh Sep 24 '18 at 15:00
  • 1
    I do not understand what I should put into my `jQuery.js` file (this file is empty for me by the way) – desmond13 May 15 '19 at 18:56
  • 1
    There is a quite nice solution: e-html element from EHTML library, it allows you to use sort of module system in HTML. https://github.com/Guseyn/EHTML – Guseyn Ismayylov Nov 20 '19 at 11:25
  • You can include files if fileuristrict is set to false in firefox. Chrome has an equivalent – Bhikkhu Subhuti Feb 29 '20 at 08:47
  • 5
    How about vanilla js? – BimaPria_4420 May 19 '21 at 12:01
  • 1
    Yeah @BimaPria_4420 this should be native. – Pim van der Heijden Jul 17 '22 at 14:03
  • This is overkill - server side includes in Apache, nginx and others were created just for this purpose and have been around for a long time. – KolonUK Jan 31 '23 at 13:24
223

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.

Trenton McKinney
  • 56,955
  • 33
  • 144
  • 158
mwiegboldt
  • 2,682
  • 2
  • 16
  • 22
  • 1
    Very useful. Is there a way to pass an argument through another data parameter, like `data-argument` and retrieve it in the included file? – chris Apr 08 '16 at 09:45
  • 1
    @chris You can use GET params e.g. `$("#postdiv").load('posts.php?name=Test&age=25');` – Nam G VU May 06 '16 at 08:08
  • 2
    not working on chrome with local files "Cross origin requests are only supported for protocol schemes: htt" – Artem Bernatskyi Sep 10 '17 at 15:41
  • 2
    @ArtemBernatskyi Does it help, when you run a local server instead? Here is an easy tutorial: https://developer.mozilla.org/en-US/docs/Learn/Common_questions/set_up_a_local_testing_server#Running_a_simple_local_HTTP_server – mwiegboldt Sep 10 '17 at 20:53
193

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>

`);
Chris Magnuson
  • 5,780
  • 7
  • 34
  • 37
Tafkadasoh
  • 4,667
  • 4
  • 27
  • 31
  • 4
    @TrevorHickey Yes, you're right, that's the drawback of my solution, and that isn't very elegant. However, as you can insert an '\' with a simple regex at the end of each line, this works for me best. Hmm... maybe I should add to my answer how to do the insertion via regex... – Tafkadasoh Apr 23 '14 at 07:59
  • 2
    It's trivial to do Ajax with plain JS and no jQuery. For starters, see http://stackoverflow.com/questions/8567114/how-to-make-an-ajax-call-without-jquery. – EML Sep 02 '14 at 09:46
  • This should be the chosen solution,using Jquery to do something as simple as this is not optimal. – Yvon Huynh Sep 18 '16 at 07:48
  • 3
    Oh sheesh, that's ugly - no thanks. I'd rather write my html as html. I don't care if I can use sed on the command line - I don't want to have to rely on that every time I change the contents of the template. – jbyrd Dec 08 '16 at 19:18
  • Does this work on any HTMl such as ones with in? – Xetrov Oct 25 '17 at 20:11
  • 1
    @Goodra It should work on any HTML without `'` marks in it. If you just do a find / replace to replace `\` with `\\` THEN find / replace to replace `'` with `\'` and new-lines with `\`new-lines it will work fine. – wizzwizz4 Nov 02 '17 at 18:22
  • 1
    @wizzwizz4: Thanks to Greg, the sed command now also escapes single quotes and backslashes. Furthermore, I've added a bash script that does all the work for you. :-) – Tafkadasoh Jan 15 '18 at 06:40
  • 1
    You can use backticks `\`` - then you are able to insert expressions like `${var}` - you then only need to escape `\\`` and `\$` – inetphantom Sep 24 '18 at 15:59
  • Oooooooohhh! Awesome! Now I can include my navigation bar without cluttering every page.. heheh! – Momoro Apr 10 '20 at 06:26
  • It worked on first try. I have tried many different things, thanks! I did the two examplefiles above and it worked, no strangeness ,thanks! – Michael Larsson Feb 21 '22 at 10:21
  • Vanilla JS is always better to me (+1). Backticks are enough, forget about the backslashes. And you dont need to use the extension .JS in the imported file, use any other. – Jose Manuel Abarca Rodríguez May 31 '22 at 17:54
  • instead of `document.write(...)`, you should use `document.currentScript.outerHTML = ...`. (this has the added bonus of removing the – 12Me21 Jun 02 '22 at 18:58
  • This is overkill - why send code to the client to be processed just to grab more files from the server? _Server side includes_ in Apache, nginx and others were created just for this purpose and have been around for a long time. – KolonUK Jan 31 '23 at 13:25
  • 1
    @KolonUK: You have to read the answer in context of the time it was written and let me tell you about my use case back then: I was working as an iOS dev and had to display an about webpage within the app (without communication to a server) that had to be localized into 7 languages, but each version contained at the bottom a long non-localized part. The answer above was the best way to go in that situation back then. – Tafkadasoh Feb 08 '23 at 01:59
  • @Tafkadasoh OK, that makes more sense - you might want to edit the question to state as much. – KolonUK Feb 08 '23 at 10:46
98

Checkout HTML5 imports via Html5rocks tutorial and at polymer-project

For example:

<head>
  <link rel="import" href="/path/to/imports/stuff.html">
</head>
Supersharp
  • 29,002
  • 9
  • 92
  • 134
user1587439
  • 1,637
  • 1
  • 12
  • 8
  • 36
    HTML imports are not meant to actually include the content in the page directly. The code in this answer only makes `stuff.html` available *as a template* within the parent page, but you'd have to use scripting to create *clones* of its DOM in the parent page so that they're visible to the user. – waldyrious Oct 25 '14 at 18:18
  • 1
    The instructions at html5rocks.com for inserting the contents of one HTML page into another don't seem to work in a lot of browsers out there, yet. I tried it in Opera 12.16 and Superbird Version 32.0.1700.7 (233448) without effect (on Xubuntu 15.04). I hear it doesn't work in Firefox (due to a bug that hopefully has been fixed) or a lot of versions of Chrome, though. So, while it looks like it may be an ideal solution in the future, it's not a cross-browser solution. – Brōtsyorfuzthrāx Aug 27 '15 at 11:29
  • 1
    Apparently not ready as of end 2016 in FireFox (45.5.1 ESR). JS console says: `TypeError: ... .import is undefined`. [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import) says "This feature is not implemented in any browsers natively at this time." Does anybody know if it is possible to build FF with this feature? – sphakka Dec 10 '16 at 15:32
  • 3
    Firefox will not support it. To enable it try to set "dom.webcomponents.enabled". It will work only in Chrome and Opera, Android with updatable web view (startng 4.4.3). Apple browsers do not support it. It looks like a nice idea for web-components but not wide implemented yet. – Maxim Jan 03 '17 at 19:51
  • 19
    Update late 2018: HTML imports are apparently being [deprecated for some reason](https://www.chromestatus.com/features/5144752345317376) – V. Rubinetti Nov 08 '18 at 01:55
  • 4
    HTML Imports are deprecated and was removed from Chrome in February 2020. – Paulo Ney Aug 26 '20 at 00:42
85

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.

Michael Marr
  • 2,101
  • 14
  • 13
  • 4
    Will this evaluate JavaScript if include.html has it embedded? – Seth Feb 18 '14 at 21:14
  • 1
    @Seth it doesn't seem to. I am going to play around with the src and see if I can make it do that. Thanks to michael-marr – xandout Oct 16 '14 at 02:29
  • 2
    Brilliant!!!! Yours seems the only solution that REPLACES the div tag used as a token for where to insert. I'm gonna study the source carefully later!! :-) – kpollock Jul 30 '16 at 14:27
  • This is it! Thanks! – miket Mar 22 '18 at 08:40
  • 1
    thanks this works, it includes the HTML/CSS but not the Javascript from source files. You just have to include it again wherever you use the `
    `. This tool makes it easier to make a simple no-plugin multipage mockup in a clean way.
    – Vincent Tang Apr 04 '18 at 18:50
  • Also, if you write inline javascript on the file calling the imports, you need to use a `setTimeOut(func,4000);` and then the calling `function func(){ /* do stuff here */});` because Javascript doesn't know when the source html/css are loaded in. As opposed to just using a jquery `$(document).ready(function(){})` – Vincent Tang Apr 04 '18 at 19:18
  • Why is this better? Because it's *literally one line of javascript* versus how many megabytes of jQuery! And it works for pure HTML. Will be using this for static headers. (Just thought I'd clarify/promo because if you don't click on the link you don't know how small it is.) – Pro Q Jul 03 '18 at 06:16
  • 1
    can I use this lib in any application? I mean how can credit the author ? W3School has similar solution, only difference it that your code caters to recursive call on window load as well ....https://www.w3schools.com/howto/tryit.asp?filename=tryhow_html_include_1 – yeppe Dec 20 '18 at 07:26
  • I have move the top menu in a separate "include" HTML file and I want to use your library to insert the top menu into the HTML. But I see a possible isue from SEO point of view. Will google see the links or it will only see the
    tag?
    – Gabriel Mar 07 '21 at 17:29
  • Not supported now. > Deprecated method of including and reusing HTML documents in other HTML documents. Superseded by ES modules. – Alex78191 Jul 06 '22 at 07:25
71

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".

bjb568
  • 11,089
  • 11
  • 50
  • 71
  • 10
    it does not seem to apply css styles from the parent page for instance. – Randy Oct 24 '14 at 21:48
  • 6
    @Randy So? This could be counted as a plus (especially for user-generated content and the like). You can easily include the css files again anyway without making another request because of caching anyway. – bjb568 Oct 24 '14 at 23:24
  • Answered my needs for the answer to this question - how to include an html file in another html file... – Grimxn Nov 10 '15 at 22:09
  • 24
    The `seamless` attribute **has been [removed](https://github.com/whatwg/html/issues/331)** from the HTML draft it came from. Don't use it. – Mitja Mar 28 '17 at 15:25
  • awesome this works work for MarkDown as well. Tested on Typora. – Foad S. Farimani Mar 13 '19 at 22:58
  • 1
    Fantastic, I can include a whole html document thas has interactive 3D plots with this. Thank you! – pglpm Jun 24 '20 at 16:04
50

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" -->
bendecko
  • 2,643
  • 1
  • 23
  • 33
Webdesign7 London
  • 775
  • 1
  • 8
  • 14
37

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]-->
bjb568
  • 11,089
  • 11
  • 50
  • 71
Aleksandar Vacić
  • 4,433
  • 35
  • 35
  • 12
    It appears that ``, `` and ` – waldyrious Oct 25 '14 at 18:24
  • 3
    iframe-seamless has been dropped from the HTML standard: https://github.com/whatwg/html/issues/331. So @waldyrious comment is not longer correct (mind to update it your comment?) – Tomáš Pospíšek Aug 26 '18 at 20:30
  • 3
    Thanks for the heads-up, @TomášPospíšek. I can't edit my comment anymore, but hopefully your response provides the necessary caveat to readers. To be clear, the last sentence (about the `seamless` attribute) is the only outdated part -- the rest still applies. – waldyrious Sep 16 '18 at 20:04
  • to not show scrollbars, should style this to be inline-block, see https://www.anycodings.com/1questions/2247104/how-to-resize-the-height-of-the-html-ampltobjectampgt-tag-dynamically-to-display-all-the-content-without-showing-the-scrollbars-duplicate – George Birbilis Oct 14 '22 at 14:34
30

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>
Mustafa Burak Kalkan
  • 1,132
  • 21
  • 28
26

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

CoolDude
  • 417
  • 1
  • 5
  • 11
  • 4
    Works like a charm and it's the cleanest solution. This should be the accepted answer. – vbocan Aug 10 '16 at 05:11
  • Agree. Just one note: do not try to do a self-closing object tag. The text after it will get erased. – Sridhar Sarnobat Nov 14 '16 at 07:53
  • It seems to create a new "#document" which automatically contains new, nested and tags. This did not work for my purpose; my .html file contains – IAM_AL_X Nov 28 '18 at 04:49
  • should style this to be inline-block, see https://www.anycodings.com/1questions/2247104/how-to-resize-the-height-of-the-html-ampltobjectampgt-tag-dynamically-to-display-all-the-content-without-showing-the-scrollbars-duplicate – George Birbilis Oct 14 '22 at 14:33
18

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

Abhishek Singh
  • 33
  • 1
  • 10
Kaj Risberg
  • 617
  • 9
  • 15
  • If you want to know when the document has been loaded, you can put this at the end of the document: Clever trick, eh? – Kaj Risberg Oct 02 '18 at 06:51
  • The `w3-include-HTML` methode is not really efficient. The script which they have wrote as an example is quite awkward and complicated. [This](https://stackoverflow.com/a/59249682/18533305) is much more efficient. – Mqx Mar 31 '23 at 08:20
17

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'); ?>
rtd1123
  • 482
  • 2
  • 7
  • 30
    Yeah that's is a very bad advice. Html files are static, and are served by apache very fast. If you add all html files to the php parser just to inlcude files, you will have a lot of performance problems on your servers. The javascript way (jQuery or plain JS) are not very good solutions, but they still are way more efficient and less dangerous than this one. – Gfra54 May 23 '14 at 08:18
  • @Gfra54 Do you mean that we will have performance issues if we use Apache only for this, and we don't do any php work for the site? Or will it slow down if I use php and this thing together? – user3459110 May 23 '14 at 15:12
  • 1
    **Caution: Adding these lines to `.htaccess` may cause `html` pages to try to download as files rather than view in browser. Test first.** *Disclaimer: That just now happened to me when I tried the above solution. My `.htaccess` was empty except for above two lines. Caution advised. Try `lolo`'s jQuery solution (below) instead.* – cssyphus Dec 29 '15 at 19:38
  • man I was complicating myself even though I have done it before. Thanks for the reminder. For the purpose I need it doesn't really affect performance so I'm cool. – Gman Jun 16 '16 at 07:08
  • Ha this performance-crushing answer is an awesome example of out-of-the-box thinking. I would never suggest it, but maybe a lifesaver when you need a quick bit of php sledgehammer. :-) – moodboom Jan 07 '17 at 15:44
  • This is overkill - server side includes in Apache, nginx and others were created just for this purpose and have been around for a long time. – KolonUK Jan 31 '23 at 13:24
13

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>
Ramtin
  • 3,058
  • 1
  • 22
  • 24
11

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>
Ben Mc
  • 139
  • 1
  • 3
9

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 :)

Dmitry Sheiko
  • 2,130
  • 1
  • 25
  • 28
  • Where should the script line go in the html File? – Andrew Truckle Oct 27 '18 at 21:07
  • Anywhere within BODY. Can be placed recursively in the content of the included files – Dmitry Sheiko Oct 29 '18 at 08:51
  • Cool HTML feature ... unfortunately, Chrome now reports: HTML Imports is deprecated and has now been removed as of M80. See https://www.chromestatus.com/features/5144752345317376 and https://developers.google.com/web/updates/2019/07/web-components-time-to-upgrade for more details. – BurninLeo Mar 16 '21 at 09:59
8

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

Amir Saniyan
  • 13,014
  • 20
  • 92
  • 137
7

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>
barro32
  • 2,559
  • 23
  • 36
7

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>
pinei
  • 2,233
  • 1
  • 24
  • 25
6

To insert contents of the named file:

<!--#include virtual="filename.htm"-->
Radim Köhler
  • 122,561
  • 47
  • 239
  • 335
St.Eve
  • 69
  • 1
  • 1
6

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

Alban Lusitanae
  • 225
  • 3
  • 12
  • this does not work in file:// I want to develop locally without a server. This only works with a server and then at that point just use SSI. Can you get this to work without a server? – Joshua Robison Jul 16 '22 at 09:31
6

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>
xmoonlight
  • 199
  • 4
  • 12
  • @Williams, thanks a lot to you for feedback my work! – xmoonlight Oct 12 '21 at 09:24
  • You can’t really claim it supports the `file://` protocol when the support amounts to an `alert()` telling you to turn off Chrome web security (CORS check). – Shaw Sep 02 '23 at 19:08
5

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)

SubLock69
  • 91
  • 1
  • 7
4

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 :)

Massa
  • 3,670
  • 1
  • 17
  • 16
  • Security problem, bacause you can send somebody this link: www.yoursite.com/a.html?p=htttp://www.linktovir.us/here.html – Mr. Hugo Oct 15 '19 at 18:43
4

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>

(stackoverflow snippet will work better (load full pages, not only message) when you first go here and push button to give your computer temporary acces to cors-anywhere)

Kamil Kiełczewski
  • 85,173
  • 29
  • 368
  • 345
4

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!

Calculamatrise
  • 364
  • 3
  • 6
3

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)

al.scvorets
  • 122
  • 9
3

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.

AndrewL64
  • 15,794
  • 8
  • 47
  • 79
2

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

Dhiral Pandya
  • 10,311
  • 4
  • 47
  • 47
  • 8
    "just use below code to import any HTML files in one line" is pretty disingenuous. You have to then write some JS to make use of any content you imported, so it ends up being way more than "one line". – skybondsor Apr 15 '17 at 13:42
  • HTML Imports are deprecated and was removed from Chrome in February 2020. – Paulo Ney Aug 26 '20 at 01:01
  • @PauloNey This isn't `import`, it's `link`. – johny why Nov 27 '22 at 20:47
2

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.

Hamza Ali
  • 380
  • 5
  • 21
2

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>
Dealazer
  • 59
  • 4
  • https://www.w3schools.com/TAgs/tag_frame.asp - HTML tag is not supported in HTML5 :( – Rublacava Jul 05 '22 at 22:34
  • If I recall correctly frames are nowadays blocked quite often since in the past they were exploited by advertisers and mostly for spreading malicious content. – rbaleksandar Sep 24 '22 at 21:46
2

w3.js is pretty cool.

https://www.w3schools.com/lib/w3.js

and we are focus

w3-include-html

but consider the below case

-  popup.html
-  popup.js
-  include.js
-  partials 
   -  head
         -  bootstrap-css.html
         -  fontawesome-css.html
         -  all-css.html
   -  hello-world.html
<!-- popup.html -->
<head>
<script defer type="module" src="popup.js"></script>
<meta data-include-html="partials/head/all-css.html">
</head>

<body>
<div data-include-html="partials/hello-world.html"></div>
</body>
<!-- bootstrap-css.html -->
<link href="https://.../bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" />

<!-- fontawesome-css.html -->
<link rel="stylesheet" href="https://.../font-awesome/5.15.4/css/all.min.css" />
<!-- all-css.html -->
<meta data-include-html="bootstrap-css.html">
<meta data-include-html="fontawesome-css.html">

<!-- 
If you want to use w3.js.include, you should change as below

<meta w3-include-html="partials/head/bootstrap-css.html">
<meta w3-include-html="partials/head/fontawesome-css.html">

Of course, you can add the above in the ``popup.html`` directly.

If you don't want to, then consider using my scripts.
-->
<!-- hello-world.html -->
<h2>Hello World</h2>

Script

// include.js

const INCLUDE_TAG_NAME = `data-include-html`

/**
 * @param {Element} node
 * @param {Function} cb callback
 * */
export async function includeHTML(node, {
  cb = undefined
}) {
  const nodeArray = node === undefined ?
    document.querySelectorAll(`[${INCLUDE_TAG_NAME}]`) :
    node.querySelectorAll(`[${INCLUDE_TAG_NAME}]`)

  if (nodeArray === null) {
    return
  }

  for (const node of nodeArray) {
    const filePath = node.getAttribute(`${INCLUDE_TAG_NAME}`)
    if (filePath === undefined) {
      return
    }

    await new Promise(resolve => {
      fetch(filePath
      ).then(async response => {
          const text = await response.text()
          if (!response.ok) {
            throw Error(`${response.statusText} (${response.status}) | ${text} `)
          }
          node.innerHTML = text
          const rootPath = filePath.split("/").slice(0, -1)
          node.querySelectorAll(`[${INCLUDE_TAG_NAME}]`).forEach(elem=>{
            const relativePath = elem.getAttribute(`${INCLUDE_TAG_NAME}`) // not support ".."
            if(relativePath.startsWith('/')) { // begin with site root.
              return
            }
            elem.setAttribute(`${INCLUDE_TAG_NAME}`, [...rootPath, relativePath].join("/"))
          })
          node.removeAttribute(`${INCLUDE_TAG_NAME}`)
          await includeHTML(node, {cb})
          node.replaceWith(...node.childNodes) // https://stackoverflow.com/a/45657273/9935654
          resolve()
        }
      ).catch(err => {
        node.innerHTML = `${err.message}`
        resolve()
      })
    })
  }

  if (cb) {
    cb()
  }
}
// popup.js

import * as include from "include.js"

window.onload = async () => {
  await include.includeHTML(undefined, {})
  // ...
}

output

<!-- popup.html -->

<head>

<link href="https://.../bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" />
<link rel="stylesheet" href="https://.../font-awesome/5.15.4/css/all.min.css" />
</head>

<body>
<h2>Hello World</h2>
</body>
Carson
  • 6,105
  • 2
  • 37
  • 45
1

I came to this topic looking for something similar, but a bit different from the problem posed by lolo. I wanted to construct an HTML page holding an alphabetical menu of links to other pages, and each of the other pages might or might not exist, and the order in which they were created might not be alphabetical (nor even numerical). Also, like Tafkadasoh, I did not want to bloat the web page with jQuery. After researching the problem and experimenting for several hours, here is what worked for me, with relevant remarks added:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
  <meta http-equiv="Content-Type" content="text/application/html; charset=iso-8859-1">
  <meta name="Author" content="me">
  <meta copyright="Copyright" content= "(C) 2013-present by me" />
  <title>Menu</title>

<script type="text/javascript">
<!--
var F000, F001, F002, F003, F004, F005, F006, F007, F008, F009,
    F010, F011, F012, F013, F014, F015, F016, F017, F018, F019;
var dat = new Array();
var form, script, write, str, tmp, dtno, indx, unde;

/*
The "F000" and similar variables need to exist/be-declared.
Each one will be associated with a different menu item,
so decide on how many items maximum you are likely to need,
when constructing that listing of them.  Here, there are 20.
*/


function initialize()
{ window.name="Menu";
  form = document.getElementById('MENU');
  for(indx=0; indx<20; indx++)
  { str = "00" + indx;
    tmp = str.length - 3;
    str = str.substr(tmp);
    script = document.createElement('script');
    script.type = 'text/javascript';
    script.src = str + ".js";
    form.appendChild(script);
  }

/*
The for() loop constructs some <script> objects
and associates each one with a different simple file name,
starting with "000.js" and, here, going up to "019.js".
It won't matter which of those files exist or not.
However, for each menu item you want to display on this
page, you will need to ensure that its .js file does exist.

The short function below (inside HTML comment-block) is,
generically, what the content of each one of the .js files looks like:
<!--
function F000()
{ return ["Menu Item Name", "./URLofFile.htm", "Description string"];
}
-->

(Continuing the remarks in the main menu.htm file)
It happens that each call of the form.appendChild() function
will cause the specified .js script-file to be loaded at that time.
However, it takes a bit of time for the JavaScript in the file
to be fully integrated into the web page, so one thing that I tried,
but it didn't work, was to write an "onload" event handler.
The handler was apparently being called before the just-loaded
JavaScript had actually become accessible.

Note that the name of the function in the .js file is the same as one
of the pre-defined variables like "F000".  When I tried to access
that function without declaring the variable, attempting to use an
"onload" event handler, the JavaScript debugger claimed that the item
was "not available".  This is not something that can be tested-for!
However, "undefined" IS something that CAN be tested-for.  Simply
declaring them to exist automatically makes all of them "undefined".
When the system finishes integrating a just-loaded .js script file,
the appropriate variable, like "F000", will become something other
than "undefined".  Thus it doesn't matter which .js files exist or
not, because we can simply test all the "F000"-type variables, and
ignore the ones that are "undefined".  More on that later.

The line below specifies a delay of 2 seconds, before any attempt
is made to access the scripts that were loaded.  That DOES give the
system enough time to fully integrate them into the web page.
(If you have a really long list of menu items, or expect the page
to be loaded by an old/slow computer, a longer delay may be needed.)
*/

  window.setTimeout("BuildMenu();", 2000);
  return;
}


//So here is the function that gets called after the 2-second delay  
function BuildMenu()
{ dtno = 0;    //index-counter for the "dat" array
  for(indx=0; indx<20; indx++)
  { str = "00" + indx;
    tmp = str.length - 3;
    str = "F" + str.substr(tmp);
    tmp = eval(str);
    if(tmp != unde) // "unde" is deliberately undefined, for this test
      dat[dtno++] = eval(str + "()");
  }

/*
The loop above simply tests each one of the "F000"-type variables, to
see if it is "undefined" or not.  Any actually-defined variable holds
a short function (from the ".js" script-file as previously indicated).
We call the function to get some data for one menu item, and put that
data into an array named "dat".

Below, the array is sorted alphabetically (the default), and the
"dtno" variable lets us know exactly how many menu items we will
be working with.  The loop that follows creates some "<span>" tags,
and the the "innerHTML" property of each one is set to become an
"anchor" or "<a>" tag, for a link to some other web page.  A description
and a "<br />" tag gets included for each link.  Finally, each new
<span> object is appended to the menu-page's "form" object, and thereby
ends up being inserted into the middle of the overall text on the page.
(For finer control of where you want to put text in a page, consider
placing something like this in the web page at an appropriate place,
as preparation:
<div id="InsertHere"></div>
You could then use document.getElementById("InsertHere") to get it into
a variable, for appending of <span> elements, the way a variable named
"form" was used in this example menu page.

Note: You don't have to specify the link in the same way I did
(the type of link specified here only works if JavaScript is enabled).
You are free to use the more-standard "<a>" tag with the "href"
property defined, if you wish.  But whichever way you go,
you need to make sure that any pages being linked actually exist!
*/

  dat.sort();
  for(indx=0; indx<dtno; indx++)
  { write = document.createElement('span');
    write.innerHTML = "<a onclick=\"window.open('" + dat[indx][1] +
                      "', 'Menu');\" style=\"color:#0000ff;" + 
                      "text-decoration:underline;cursor:pointer;\">" +
                      dat[indx][0] + "</a> " + dat[indx][2] + "<br />";
    form.appendChild(write);
  }
  return;
}

// -->
</script>
</head>

<body onload="initialize();" style="background-color:#a0a0a0; color:#000000; 

font-family:sans-serif; font-size:11pt;">
<h2>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;MENU
<noscript><br /><span style="color:#ff0000;">
Links here only work if<br />
your browser's JavaScript<br />
support is enabled.</span><br /></noscript></h2>
These are the menu items you currently have available:<br />
<br />
<form id="MENU" action="" onsubmit="return false;">
<!-- Yes, the <form> object starts out completely empty -->
</form>
Click any link, and enjoy it as much as you like.<br />
Then use your browser's BACK button to return to this Menu,<br />
so you can click a different link for a different thing.<br />
<br />
<br />
<small>This file (web page) Copyright (c) 2013-present by me</small>
</body>
</html>
HoldOffHunger
  • 18,769
  • 10
  • 104
  • 133
1

Using ES6 backticks ``: template literals!

let nick = "Castor", name = "Moon", nuts = 1

more.innerHTML = `

<h1>Hello ${nick} ${name}!</h1>

You collected ${nuts} nuts so far!

<hr>

Double it and get ${nuts + nuts} nuts!!

` 
<div id="more"></div>

This way we can include html without encoding quotes, include variables from the DOM, and so on.

It is a powerful templating engine, we can use separate js files and use events to load the content in place, or even separate everything in chunks and call on demand:

let inject = document.createElement('script');
inject.src= '//....com/template/panel45.js';
more.appendChild(inject);

https://caniuse.com/#feat=template-literals

NVRM
  • 11,480
  • 1
  • 88
  • 87
  • Hey, you are right, in 2018 the above was a clear sign of an actual good RTFM ;) I largely smashed up that `javascript` badge as a hobby programmer till then. – NVRM Jun 07 '20 at 16:00
1

I have one more solution to do this

Using Ajax in javascript

here is the explained code in Github repo https://github.com/dupinder/staticHTML-Include

basic idea is:

index.html

<!DOCTYPE html>
<html>
<head>
    <meta charset='utf-8'>
    <meta http-equiv='X-UA-Compatible' content='IE=edge'>
    <title>Page Title</title>
    <meta name='viewport' content='width=device-width, initial-scale=1'>
    <script src='main.js'></script>


</head>
<body>
    <header></header>

    <footer></footer>
</body>
</html>

main.js

fetch("./header.html")
  .then(response => {
    return response.text()
  })
  .then(data => {
    document.querySelector("header").innerHTML = data;
  });

fetch("./footer.html")
  .then(response => {
    return response.text()
  })
  .then(data => {
    document.querySelector("footer").innerHTML = data;
  });
Dupinder Singh
  • 7,175
  • 6
  • 37
  • 61
  • This does not run attached js functions in the importing file. Do you have any solution for that? – EDPChinthana Aug 04 '20 at 11:48
  • 1
    If you are trying to run `some.js` file which is linked in `footer.html` or `header.html` then you are perceiving this in a wrong way. This solution is just for HTML components plug-in in a web page. You need to create a JS plugin which will import all your required JS file – Dupinder Singh Aug 04 '20 at 12:35
  • URL scheme "file" is not supported. – MD. RAKIB HASAN Jan 09 '22 at 10:48
1

Using just HTML it is not possible to include HTML file in another HTML file. But here is a very easy method to do this. Using this JS library you can easy do that. Just use this code:

<script> include('path/to/file.html', document.currentScript) </script>
PSEUDO
  • 113
  • 4
  • 13
  • link gives a 404 – Catweazle May 12 '21 at 15:34
  • I actually like the syntax. Can be even more concise like `` The original implementation sucks though. It deals with CSS and all that stuff for some reason. You can add styles inside of body! https://stackoverflow.com/questions/4957446/load-external-css-file-in-body-tag#comment19176804_4957526 – Brian Cannard Feb 11 '22 at 03:40
  • @BrianCannard Actually the reason of passing `document.currentScript` as an argument is that it is used to insert the imported code to DOM. But if you have a solution of inserting imported code to DOM without passing this argument then you're welcome to provide a solution in the gist comment. – PSEUDO Feb 11 '22 at 10:49
0

PHP is a server level scripting language. It can do many things, but one popular use is to include HTML documents inside your pages, much the same as SSI. Like SSI, this is a server level technology. If you are not sure if you have PHP functionality on your website contact your hosting provider.

Here is a simple PHP script you can use to include a snippet of HTML on any PHP-enabled web page:

Save the HTML for the common elements of your site to separate files. For example, your navigation section might be saved as navigation.html or navigation.php. Use the following PHP code to include that HTML in each page.

<?php require($DOCUMENT_ROOT . "navigation.php"); ?>

Use that same code on every page that you want to include the file. Make sure to change the higlighted file name to the name and path to your include file.

DontVoteMeDown
  • 21,122
  • 10
  • 69
  • 105
0

If you use some framework like django/bootle, they often ship some template engine. Let's say you use bottle, and the default template engine is SimpleTemplate Engine. And below is the pure html file

$ cat footer.tpl
<hr> <footer>   <p>&copy; stackoverflow, inc 2015</p> </footer>

You can include the footer.tpl in you main file, like:

$ cat dashboard.tpl
%include footer

Besides that, you can also pass parameter to your dashborard.tpl.

jaseywang
  • 29
  • 4
0

Based on the answer of https://stackoverflow.com/a/31837264/4360308 I've implemented this functionality with Nodejs (+ express + cheerio) as follows:

HTML (index.html)

<div class="include" data-include="componentX" data-method="append"></div>
<div class="include" data-include="componentX" data-method="replace"></div>

JS

function includeComponents($) {
    $('.include').each(function () {
        var file = 'view/html/component/' + $(this).data('include') + '.html';
        var dataComp = fs.readFileSync(file);
        var htmlComp = dataComp.toString();
        if ($(this).data('method') == "replace") {
            $(this).replaceWith(htmlComp);
        } else if ($(this).data('method') == "append") {
            $(this).append(htmlComp);
        }
    })
}

function foo(){
    fs.readFile('./view/html/index.html', function (err, data) {
        if (err) throw err;
        var html = data.toString();
        var $ = cheerio.load(html);
        includeComponents($);
        ...
    }
}

append -> includes the content into the div

replace -> replaces the div

you could easily add more behaviours following the same design

Community
  • 1
  • 1
giroxiii
  • 655
  • 5
  • 14
0

I strongly suggest AngularJS's ng-include whether your project is AngularJS or not.

<script src=".../angular.min.js"></script>

<body ng-app="ngApp" ng-controller="ngCtrl">

    <div ng-include="'another.html'"></div> 

    <script>
        var app = angular.module('ngApp', []);
        app.controller('ngCtrl', function() {});
    </script>

</body>

You can find CDN (or download Zip) from AngularJS and more information from W3Schools.

ghchoi
  • 4,812
  • 4
  • 30
  • 53
0

Whatever method you choose please check that it works for all relevant browsers. This method listed at w3schools passes the test with these browsers:

  • chrome desktop
  • firefox desktop
  • chrome android

You can improve that and put the javascript in a separate file:

<head>
<script src='include_html.js'></script>
</head>
<body>
<div w3-include-html="your_content.html"></div> 
<script>
includeHTML();
</script>
</body>
wromma
  • 21
  • 1
  • 5
0

Technically this doesn't include an HTML file, but it will let you use HTML syntax in a JavaScript file and import that. Many code editors (including VS Code) can also format it as HTML.

Main HTML file:

<script src="./include.js"></script>

<div id="include-here"></div>

<script>
    document.addEventListener("DOMContentLoaded", function () {
        const element = document.querySelector('#include-here')
        element.innerHTML = html
    })
</script>

include.js:

const html = `
<body>

<p>here</p>

</body>
`

You can rename 'include.js' to 'include.html' and it should work the same. Many code editors will then format the file as HTML (else you can manually tell the browser to format it as HTML).

Andre OBrien
  • 160
  • 1
  • 11
0

No need for jQuery... Here is my solution, I have an external HTML file containing some JavaScript as well which is required to be executed.

I have some code snipped that is integrated as a "widget" in another web application. I test the "widget" within a mock website. It's used in a test environment.

I personally would refrain from doing something like this in a production environment and would rather use a framework such as Angular or React.


main.html

<div id="plugin"></div>
<script>
    void async function () {

        const htmlFile = await fetch('plugin.html');
        const plugin = document.getElementById('plugin');
        plugin.innerHTML = await htmlFile.text();

        const scriptElements = Array.from(plugin.getElementsByTagName('script'));

        for (const scriptElement of scriptElements) {
            
            const newScriptElement = document.createElement('script'); 

            newScriptElement.text = scriptElement.text;
            if (!!scriptElement.src) {
                newScriptElement.src = scriptElement.src;
            }

            plugin.appendChild(newScriptElement);
            scriptElement.remove();

            await new Promise((resolve, reject) => {
                const timeout = setTimeout(() => resolve(), 2000);
                newScriptElement.onload = () => {
                    clearTimeout(timeout);
                    resolve();
                };
            });

        }

    } ()
</script>

plugin.html

<style>
    #map { height: 500px; }
</style>

<div id="map"></div>

<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" />
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>

<script>

    let map = L.map('map').setView([22.31, 114.17], 13);

    L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
        maxZoom: 19,
        attribution: `&copy; <a href="http://www.openstreetmap.org/copyright">
                      OpenStreetMap</a>`
    }).addTo(map);

</script>

Source: https://gist.github.com/moosetraveller/6a3a029287b8aa3621d23d84962f6f1a

Caveat: If your injected script uses document.write, your document may disappear as it does not write out to where it was intended to.


If you just want to add HTML without JavaScript content:

<div id="plugin"></div>

<script>

    void async function () {

        const htmlFile = await fetch('plugin.html');
        const plugin = document.getElementById('plugin');
        plugin.innerHTML = await htmlFile.text();

    } ()

</script>
Thomas
  • 8,357
  • 15
  • 45
  • 81
-1

Well, if all you're wanting to do is put text from a separate file into your page (tags in the text should work, too), you can do this (your text styles on the main page—test.html—should still work):

test.html

<html>
<body>
<p>Start</p>

<p>Beginning</p>

<div>
<script language="JavaScript" src="sample.js"></script>
</div>

<p>End</p>

</body>
</html>

sample.js

var data="Here is the imported text!";
document.write(data);

You can always recreate the HTML tags you want yourself, after all. There's need for server-side scripting just to grab text from another file, unless you want to do something more.

Anyway, what I'm starting to use this for is to make it so if I update a description common among lots of HTML files, I only need to update one file to do it (the .js file) instead of every single HTML file that contains the text.

So, in summary, instead of importing an .html file, a simpler solution is to import a .js file with the content of the .html file in a variable (and write the contents to the screen where you call the script).

Thanks for the question.

Brōtsyorfuzthrāx
  • 4,387
  • 4
  • 34
  • 56
-7

using jquery u need import library

i recommend you using php

<?php
    echo"<html>   
          <body>";
?> 
<?php
    include "b.html";
?>
<?php
    echo" </body> 
        </html>";
?>

b.html

<div>hi this is ur file :3<div>
Bear Bear
  • 9
  • 2