AngularJS ng-include: Include HTML Files with Example

โšก Smart Summary

ng-include in AngularJS fetches, compiles and injects an external HTML fragment into the main page, so shared markup such as a table, a header or a footer lives in one reusable partial file.

  • ๐Ÿ”˜ Directive role: ng-include fetches an external fragment and inserts it as child nodes of its host element.
  • โ˜‘๏ธ Quoted path: The src value is an expression, so a literal file name needs single quotes inside the attribute.
  • โœ… Worked example: Table.html renders through ng-repeat once Main.html injects it into the controller div.
  • ๐Ÿงช New child scope: Each include builds a child scope, so primitive bindings require dot notation.
  • ๐Ÿ› ๏ธ Blank include: Same-origin rules, $sce and file access explain most empty results.
  • ๐Ÿ“Š Version note: AngularJS support ended January 2022; modern Angular composes components instead.

ng-include directive in AngularJS injecting an external HTML file into the main template

By default, HTML does not provide the facility to include client-side code from other files. Itโ€™s normally a good practice in any programming language to distribute functionality across various files for any application.

For example, if you had logic for numeric operations, you would normally want to have that functionality defined in one separate file. That separate file could then be re-used across multiple applications by just including that file.

This is normally the concept of Include statements which are available in programming languages such as .Net and Java.

This tutorial looks at other ways files (files which contain external HTML code) can be included in the main HTML file.

Client Side Includes

One of the most common ways to include HTML code is via JavaScript. JavaScript is a programming language which can be used to manipulate the content in an HTML page on the fly. Hence, JavaScript can also be used to include code from other files.

The below steps show how this can be accomplished.

Step 1) Define a file called Sub.html and add the following code to the file.

<div>
	This is an included file
</div>

Step 2) Create a file called Sample.html, which is your main application file and add the below code snippet.

Below are the main aspects to note about the below code,

  1. In the body tag, there is a div tag which has an id of Content. This is the place where the code from the external file โ€˜Sub.htmlโ€™ will be inserted.
  2. There is a reference to a jQuery script. jQuery is a scripting language built on top of JavaScript which makes DOM manipulation even easier.
  3. In the JavaScript function, there is a statement โ€˜$(โ€œ#Contentโ€).load(โ€œSub.htmlโ€);โ€™ which causes the code in the file Sub.html to be injected in the div tag which has the id of Content.
    <html> 
    	  <head> 
    	    <script src="jquery.js"></script> 
    	    <script> 
    	    $(function(){
    	      $("#Content").load("Sub.html"); 
    	    });
        </script> 
      </head> 
    
    <body> 
         <div id="Content"></div>
      </body> 
    </html>

Server Side Includes

Server Side Includes are also available for including a common piece of code throughout a site. This is normally done for including content in the below parts of an HTML document.

  1. Page header
  2. Page footer
  3. Navigation menu.

For a web server to recognize a Server Side Include, the file names have special extensions. They are usually accepted by the web server such as .shtml, .stm, .shtm, .cgi.

The directive used for including content is the โ€œinclude directiveโ€. An example of the include directive is shown below:

<!--#include virtual="navigation.cgi" -->
  • The above directive allows the content of one document to be included in another.
  • The โ€œvirtualโ€ command above code is used to specify the target relative to the domain root of the application.
  • Also, to the virtual parameter, there is also the file parameter which can be used. The โ€œfileโ€ parameters are used when one needs to specify the path relative to the directory of the current file.

Note:

The virtual parameter is used to specify the file (HTML page, text file, script, etc.) that needs to be included. If the web server process does not have access to read the file or execute the script, the include command will fail. The โ€˜virtualโ€™ word is a keyword that is required to be placed in the include directive.

How to include HTML file in AngularJS

AngularJS provides the function to include the functionality from other AngularJS files by using the ng-include directive.

The primary purpose of the โ€œng-include directiveโ€ is to fetch, compile and include an external HTML fragment in the main AngularJS application.

Version note: AngularJS 1.x left Long Term Support on 31 December 2021, and the framework team states that AngularJS support officially ended in January 2022, so no releases or security patches follow. Every step and code block below stays exactly as published, as the historical reference. Modern Angular ships no direct replacement: markup is composed from components, and a fragment picked at runtime is rendered with ng-container and ngComponentOutlet.

Letโ€™s look at the below code base and explain how this can be achieved using AngularJS.

Step 1) letโ€™s write the below code in a file called Table.html. This is the file which will be injected into our main application file using the ng-include directive.

The below code snippet assumes that there is a scope variable called โ€œtutorial.โ€ It then uses the ng-repeat directive, which goes through each topic in the โ€œtutorialโ€ variable and displays the values for the โ€˜Nameโ€™ and โ€˜Descriptionโ€™ key-value pair.

<table>
    <tr ng-repeat="Topic in tutorial">
        <td>{{ Topic.Name }}</td>
        <td>{{ Topic.Description }}</td>
    </tr>
</table>

Step 2) letโ€™s write the below code in a file called Main.html. This is a simple AngularJS application which has the following aspects

  1. Use the โ€œng-include directiveโ€ to inject the code in the external file โ€˜Table.htmlโ€™. The statement has been highlighted in bold in the below code. So the div tag โ€˜ <div ng-include=”‘Table.html'”></div>โ€™ will be replaced by the entire code in the โ€˜Table.htmlโ€™ file.
  2. In the controller, a โ€œtutorialโ€ variable is created as part of the $scope object. This variable contains a list of key-value pairs.

In our example, the key value pairs are

  1. Name โ€“ This denotes the name of a topic such as Controllers, Models, and Directives.
  2. Description โ€“ This gives a description of each topic

The tutorial variable is also accessed in the โ€˜Table.htmlโ€™ file.

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Event Registration</title>
        <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
</head>
<body ng-app="sampleApp">
<div ng-controller="AngularController">
    <h3> Guru99 Global Event</h3>
		<div ng-include="'Table.html'"></div>
</div>
<script>

    var sampleApp = angular.module('sampleApp',[]);
    sampleApp.controller('AngularController', function($scope) {
        $scope.tutorial =[
            {Name: "Controllers" , Description : "Controllers in action"},
            {Name: "Models" , Description : "Models and binding data"},
            {Name: "Directives" , Description : "Flexibility of Directives"}
        ];

    });
</script>
</body>
</html>

When you execute the above code, you will get the following output.

Output:

The capture below shows the rendered result: the browser tab carries the title Event Registration, the heading sits above the injected table, and the three rows are drawn from the tutorial array in Main.html through the partial. The annotated screenshot spells the heading Gur99 while the code writes Guru99.

Browser output of the AngularJS ng-include example showing the topic table injected from Table.html

ng-include Attributes: src, onload and autoscroll

Beyond the file name the directive accepts two optional attributes, and it can be written three ways: as an attribute on any element, as an <ng-include> element, or as a CSS class. The reference below follows the official ngInclude documentation.

Attribute Required What it does
src, or ng-include Yes Expression that evaluates to the template URL
onload No Expression evaluated each time a new partial finishes loading
autoscroll No Calls $anchorScroll after the content loads; omitting the attribute disables scrolling
<div ng-include="'Table.html'" onload="loaded = true" autoscroll></div>
<ng-include src="templateUrl"></ng-include>

The most common mistake follows from the first row: src takes an expression, not a plain string. A literal path therefore needs its own quotes inside the attribute, which is why the example above reads ng-include="'Table.html'". Writing ng-include="Table.html" makes AngularJS evaluate Table as a scope property, find nothing, and leave the element empty.

Why ng-include Creates a New Child Scope

The directive does not paste markup into the surrounding scope. Every include creates a new child scope that inherits prototypally from the scope it was declared in, and that one fact explains most binding surprises.

Reading works as expected. The partial above reads tutorial straight from the parent, which is why ng-repeat finds the array. Writing is where it breaks: when a partial assigns to a primitive, as with ng-model="topic", AngularJS creates topic on the child scope and the parent copy never changes.

Two habits avoid the trap:

  • Bind through an object, as in ng-model="data.topic", so parent and child reach the same reference.
  • Hold the state in a controller or a service and expose functions instead of bare primitives.

The include also emits $includeContentRequested, $includeContentLoaded and $includeContentError, so a parent can react through $scope.$on without reaching into the child scope at all.

How to Fix a Blank or Failed ng-include

An include that renders nothing usually fails for one of a handful of reasons. Work through them in this order.

  1. Check the quotes. A literal file name needs single quotes inside the attribute value. Without them the expression resolves to undefined and no request is ever sent.
  2. Serve the page over HTTP. The directive issues an XHR for the partial, so opening Main.html straight from disk through a file address fails in most browsers. Any local web server clears this.
  3. Confirm the path resolves. Watch the network panel for the request. A 404 means the path is relative to the page that hosts the include, not to the partial that references it.
  4. Respect the same-origin rule. By default the template URL must match the domain and protocol of the application document, because AngularJS passes it through $sce.getTrustedResourceUrl. A template from elsewhere needs an entry in the trusted resource URL list, or an explicit trustAsResourceUrl wrapper, and the remote server still has to send CORS headers.
  5. Listen for the failure. $includeContentError fires whenever the response status falls outside 200 to 299, turning a silently blank area into a message worth logging.

One more cause is easy to miss. AngularJS keeps every fetched partial in $templateCache, so an edited file can keep serving stale markup until the cache entry is removed or the page is reloaded from source. When a fragment needs behaviour of its own rather than markup alone, a custom directive with its own template and isolated scope is the better tool.

FAQs

ng-include injects a fragment you name yourself, anywhere on the page. ng-view renders whichever template the router maps to the current URL, and only one ng-view belongs in a layout.

No. A partial holds a fragment only. Wrapping it in html, head or body tags leaves stray elements behind, because the markup is inserted as child nodes of the host element rather than parsed as a document.

No. The fragment is compiled and inserted as DOM nodes, so inline script elements never execute. Load shared scripts from the host page, or move the behaviour into a controller or a directive.

Yes. With ngAnimate loaded, the directive fires an enter animation on the incoming fragment and a leave animation on the outgoing one, and the two run concurrently whenever the source expression changes.

Yes. Because the value is an expression, pointing it at a scope property swaps the fragment whenever that property changes. Guard the element with ng-if so nothing loads until the property holds a real path.

No equivalent exists. Reusable markup becomes a component, and a fragment chosen at runtime renders through ngComponentOutlet or ngTemplateOutlet inside an ng-container.

Language models read a legacy template set and group partials, controllers and bindings into candidate components, then propose a migration order. Treat the output as a first draft, because scope inheritance rarely maps cleanly onto component inputs.

GitHub Copilot agent mode converts a partial into a standalone component with typed inputs and rewrites the host template, yet the generated bindings and tests still need human review.

Summarize this post with: