Transclusion error: Directive requires ng-transclude

Loading

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

Leave a Reply

Your email address will not be published. Required fields are marked *