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.
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,
- 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.
- There is a reference to a jQuery script. jQuery is a scripting language built on top of JavaScript which makes DOM manipulation even easier.
- 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.
- Page header
- Page footer
- 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
- 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.
- 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
- Name โ This denotes the name of a topic such as Controllers, Models, and Directives.
- 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.
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.
- 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.
- 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.
- 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.
- 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.
- 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.

