diff --git a/changelog_unreleased/angular/19431.md b/changelog_unreleased/angular/19431.md
new file mode 100644
index 000000000..e4875bba5
--- /dev/null
+++ b/changelog_unreleased/angular/19431.md
@@ -0,0 +1,29 @@
+#### Support `@content` block (#19431 by @fisker)
+
+
+```html
+
+
+ @content(icon) {
+ Icon
+ }
+ @content(description) {
+ Description text
+ }
+ Other children
+
+
+
+SyntaxError: Unexpected character "EOF" (Do you have an unescaped "{" in your template? Use "{{ '{' }}") to escape it.) (9:15)
+
+
+
+ @content(icon) {
+ Icon!
+ }
+ @content(description) {
+ Description text
+ }
+ Other children
+
+```
diff --git a/src/language-html/print/angular-control-flow-block-settings.evaluate.js b/src/language-html/print/angular-control-flow-block-settings.evaluate.js
index 9d5161e91..bc9b33c23 100644
--- a/src/language-html/print/angular-control-flow-block-settings.evaluate.js
+++ b/src/language-html/print/angular-control-flow-block-settings.evaluate.js
@@ -20,4 +20,4 @@ const ANGULAR_CONTROL_FLOW_BLOCK_SETTINGS = new Map(
.map(([name, followingBlockNames]) => [name, new Set(followingBlockNames)]),
);
-export default ANGULAR_CONTROL_FLOW_BLOCK_SETTINGS;
+export { ANGULAR_CONTROL_FLOW_BLOCK_SETTINGS };
diff --git a/src/language-html/print/angular-control-flow-block.js b/src/language-html/print/angular-control-flow-block.js
index d55fe5eb2..95eafa604 100644
--- a/src/language-html/print/angular-control-flow-block.js
+++ b/src/language-html/print/angular-control-flow-block.js
@@ -7,9 +7,11 @@ import {
softline,
} from "../../document/index.js";
import { hasPrettierIgnore } from "../utilities/index.js";
-import ANGULAR_CONTROL_FLOW_BLOCK_SETTINGS from "./angular-control-flow-block-settings.evaluate.js";
+import { ANGULAR_CONTROL_FLOW_BLOCK_SETTINGS } from "./angular-control-flow-block-settings.evaluate.js";
import { printChildren } from "./children.js";
+const blocksShouldNotPrintSpaceAfterName = new Set(["content"]);
+
function printAngularControlFlowBlock(path, options, print) {
const { node } = path;
const docs = [];
@@ -26,7 +28,12 @@ function printAngularControlFlowBlock(path, options, print) {
}
if (node.parameters) {
- docs.push(" (", group(print("parameters")), ")");
+ docs.push(
+ blocksShouldNotPrintSpaceAfterName.has(node.name) ? "" : " ",
+ "(",
+ group(print("parameters")),
+ ")",
+ );
}
if (!isSwitchFallthroughCase(node)) {
diff --git a/tests/format/angular/control-flow/__snapshots__/format.test.js.snap b/tests/format/angular/control-flow/__snapshots__/format.test.js.snap
index f2192d6ea..00682d5a2 100644
--- a/tests/format/angular/control-flow/__snapshots__/format.test.js.snap
+++ b/tests/format/angular/control-flow/__snapshots__/format.test.js.snap
@@ -75,6 +75,35 @@ parsers: ["angular"]
================================================================================
`;
+exports[`content.html format 1`] = `
+====================================options=====================================
+parsers: ["angular"]
+ printWidth: 80 (default) |
+=====================================input======================================
+
+ @content(icon) {
+ Icon!
+ }
+ @content(description) {
+ Description text
+ }
+ Other children
+
+
+=====================================output=====================================
+
+ @content(icon) {
+ Icon!
+ }
+ @content(description) {
+ Description text
+ }
+ Other children
+
+
+================================================================================
+`;
+
exports[`default-never.html format 1`] = `
====================================options=====================================
parsers: ["angular"]
diff --git a/tests/format/angular/control-flow/content.html b/tests/format/angular/control-flow/content.html
new file mode 100644
index 000000000..0e8e013fd
--- /dev/null
+++ b/tests/format/angular/control-flow/content.html
@@ -0,0 +1,9 @@
+
+ @content(icon) {
+ Icon!
+ }
+ @content(description) {
+ Description text
+ }
+ Other children
+