![]()
If you see the error “Directive requires ng-transclude”, it means your directive is configured for transclusion, but the template is missing the ng-transclude directive.
1️⃣ What is Transclusion in AngularJS?
Transclusion allows a directive to include the original content inside its template while still applying its own structure.
Example:
<my-directive>
<p>This content will be transcluded.</p>
</my-directive>
Inside the directive, this <p> element is injected where ng-transclude is placed.
2️⃣ Common Causes & Fixes
Cause 1: Missing ng-transclude Inside the Directive Template
If transclude: true is set in the directive but ng-transclude is missing in the template, Angular throws an error.
Problematic Code
app.directive("myDirective", function() {
return {
restrict: "E",
transclude: true, // Transclusion enabled
template: "<div class='box'><h3>Title</h3></div>" // Missing ng-transclude
};
});
<my-directive>
<p>This content should be inside the directive</p>
</my-directive>
Problem: The <p> content is ignored.
Solution: Add ng-transclude
app.directive("myDirective", function() {
return {
restrict: "E",
transclude: true,
template: "<div class='box'><h3>Title</h3><div ng-transclude></div></div>"
};
});
<my-directive>
<p>This content will now be transcluded.</p>
</my-directive>
Now the <p> inside <my-directive> is included in the output.
Cause 2: Using transclude: true Without Specifying a scope
Transclusion works best with an inherited scope. Using scope: {} creates an isolated scope, which may prevent transclusion from working.
Problematic Code
app.directive("myDirective", function() {
return {
restrict: "E",
transclude: true,
scope: {}, // Isolated scope prevents inheritance
template: "<div><h3>Title</h3><div ng-transclude></div></div>"
};
});
Solution: Use scope: false (or remove it)
app.directive("myDirective", function() {
return {
restrict: "E",
transclude: true,
scope: false, // Inherits from parent scope
template: "<div><h3>Title</h3><div ng-transclude></div></div>"
};
});
Now, the transcluded content can access parent scope variables.
Cause 3: Using Transclusion with templateUrl but Forgetting ng-transclude
If you’re using templateUrl, the file must include ng-transclude.
Problematic Code
app.directive("myDirective", function() {
return {
restrict: "E",
transclude: true,
templateUrl: "my-template.html"
};
});
my-template.html (Missing ng-transclude):
<div>
<h3>Title</h3>
</div>
Solution: Add ng-transclude in my-template.html
<div>
<h3>Title</h3>
<div ng-transclude></div> <!-- Now it will work -->
</div>
Cause 4: Using replace: true (Deprecated)
replace: true can break transclusion in newer AngularJS versions.
Problematic Code
app.directive("myDirective", function() {
return {
restrict: "E",
transclude: true,
replace: true, // Deprecated and causes transclusion issues
template: "<div><h3>Title</h3><div ng-transclude></div></div>"
};
});
Solution: Remove replace: true
replace: false // Or just remove this line (default is false)
3️⃣ Transclusion with Named Slots
You can also use named transclusion to insert different content into specific parts of the directive.
Example: Named Transclusion
app.directive("myDirective", function() {
return {
restrict: "E",
transclude: {
header: "headerContent",
body: "bodyContent"
},
template: `
<div class='box'>
<h3 ng-transclude="header"></h3>
<p ng-transclude="body"></p>
</div>
`
};
});
<my-directive>
<div header-content>Header Title</div>
<div body-content>Main body content</div>
</my-directive>
Header and body contents are inserted separately.
4️⃣ Debugging Steps
✔️ Check the console (F12 → Console Tab) for AngularJS errors
✔️ Ensure ng-transclude is present in the directive’s template
✔️ Avoid replace: true (deprecated)
✔️ Check if scope: false is needed for inherited scope
✔️ Ensure transclude: true is set in the directive
