createCommentOverlay
The entry point — its two overloads, the instance it returns, and the two module-level helpers that ship beside it.
import createCommentOverlay, {
createCommentOverlay as named,
readCommentLinkParam,
DEFAULT_LINK_PARAM,
CommentOverlay,
} from 'helldots';createCommentOverlay is both the default and a named export. The class,
CommentOverlay, is exported too — you rarely need it as a value, but it is the
type you annotate an instance with.
Signature
The function has two overloads, discriminated by autoInit.
// Mounts immediately (the default).
function createCommentOverlay(
options?: CommentOverlayOptions & { autoInit?: true },
): CommentOverlay;
// Nothing is mounted; you get an initializer to call when you are ready.
function createCommentOverlay(
options: CommentOverlayOptions & { autoInit: false },
): () => CommentOverlay;Mounting immediately
const overlay = createCommentOverlay({
user: { name: 'Ana' },
persistence: 'localStorage',
});Safe to call before the document is ready — the instance defers its own DOM work
to DOMContentLoaded. It is not safe to call outside a browser; see
server-rendered apps.
Deferring the mount
const init = createCommentOverlay({ autoInit: false, user });
if (session.isStaff) {
const overlay = init();
}Useful when the widget should appear only for a subset of users, or behind a feature flag, without paying for the mount in the meantime.
onReady is the safe point
When the document is already parsed, the mount happens inside the
constructor — before createCommentOverlay() has returned anything to assign.
That is why onReady receives the instance:
createCommentOverlay({
onReady: async (overlay) => {
const { orphaned } = overlay.loadComments(await api.get('/comments'));
if (orphaned) console.info(`${orphaned} comments lost their element`);
},
});loadComments() called earlier is not lost — the data is held and replayed at
mount — but its counts come back as zeroes, because nothing has been resolved
against the DOM yet.
Constructing the class directly
import { CommentOverlay } from 'helldots';
const overlay = new CommentOverlay({ user: { name: 'Ana' } });The constructor takes Omit<CommentOverlayOptions, 'autoInit'> — the flag only
means something to the factory. There is no reason to prefer this over
createCommentOverlay.
Module-level helpers
Two exports exist so a host can read a deep link before an overlay exists — to fetch just that one comment.
Prop
Type
import { readCommentLinkParam } from 'helldots';
const id = readCommentLinkParam();
const only = id ? [await api.get(`/comments/${id}`)] : [];Pass the same param the widget was configured with if you overrode
linkParam.
Tearing it down
overlay.cleanup();Removes the widget entirely — markers, toolbar, listeners, shadow root. This is what makes the React pattern safe under a development double-mount, and what you call on logout.
useEffect(() => {
const overlay = createCommentOverlay({ user });
return () => overlay.cleanup();
}, [user]);