diff --git a/extensions/amp-facebook-comments/1.0/storybook/Basic.amp.js b/extensions/amp-facebook-comments/1.0/storybook/Basic.amp.js
index c4211604bd1b..28129c9d13da 100644
--- a/extensions/amp-facebook-comments/1.0/storybook/Basic.amp.js
+++ b/extensions/amp-facebook-comments/1.0/storybook/Basic.amp.js
@@ -51,7 +51,11 @@ export const _default = () => {
data-locale={locale}
data-numposts={numPosts}
data-order-by={orderBy}
- >
+ >
+
+
Placeholder
+
+
);
};
diff --git a/src/preact/base-element.js b/src/preact/base-element.js
index b469e892bc30..46db3d10c73b 100644
--- a/src/preact/base-element.js
+++ b/src/preact/base-element.js
@@ -114,8 +114,11 @@ const SHADOW_CONTAINER_ATTRS = dict({
'part': 'c',
});
+/** @const {string} */
+const SERVICE_SLOT_NAME = 'i-amphtml-svc';
+
/** @const {!JsonObject} */
-const SERVICE_SLOT_ATTRS = dict({'name': 'i-amphtml-svc'});
+const SERVICE_SLOT_ATTRS = dict({'name': SERVICE_SLOT_NAME});
/**
* The same as `applyFillContent`, but inside the shadow.
@@ -624,6 +627,8 @@ export class PreactBaseElement extends AMP.BaseElement {
SERVICE_SLOT_ATTRS
);
shadowRoot.appendChild(serviceSlot);
+ this.getPlaceholder()?.setAttribute('slot', SERVICE_SLOT_NAME);
+ this.getFallback()?.setAttribute('slot', SERVICE_SLOT_NAME);
}
this.container_ = container;
diff --git a/test/unit/preact/test-base-element-mapping.js b/test/unit/preact/test-base-element-mapping.js
index 9334295f3b1b..b71305e9f31f 100644
--- a/test/unit/preact/test-base-element-mapping.js
+++ b/test/unit/preact/test-base-element-mapping.js
@@ -351,6 +351,8 @@ describes.realWin('PreactBaseElement', spec, (env) => {
element = html`
+ foo
+ bar
`;
});
@@ -373,6 +375,23 @@ describes.realWin('PreactBaseElement', spec, (env) => {
).to.have.lengthOf(1);
});
+ it('should pass placeholder and fallback elements to service slot', async () => {
+ doc.body.appendChild(element);
+ await element.buildInternal();
+ await waitFor(() => component.callCount > 0, 'component rendered');
+ const serviceSlot = element.shadowRoot.querySelectorAll(
+ 'slot[name="i-amphtml-svc"]'
+ );
+ expect(serviceSlot).to.have.lengthOf(1);
+ const placeholder = element.querySelector('[placeholder]');
+ const fallback = element.querySelector('[fallback]');
+ expect(placeholder.getAttribute('slot')).to.equal('i-amphtml-svc');
+ expect(fallback.getAttribute('slot')).to.equal('i-amphtml-svc');
+ expect(serviceSlot[0].assignedElements()).to.have.lengthOf(2);
+ expect(serviceSlot[0].assignedElements()[0]).to.equal(placeholder);
+ expect(serviceSlot[0].assignedElements()[1]).to.equal(fallback);
+ });
+
describe('SSR', () => {
let shadowRoot, container;
let componentEl, serviceSlotEl, styleEl;