Set featured image without posting it in the topic

I think usually the name is added in the alt attribute. When I upload a file, the name is usually added in front of the size in markdown, and that’s the part used by “alt”.

So hide-this-image-vacations-2025.jpg would become ![hide-this-image-vacations-2025|500x500](upload://wDxG1UR10Uj4bCO9l3pUbJvBAW5.png)

and could be hidden with

.cooked img[alt="hide-this-image-vacations-2025"] {
  display: none;
}

Since I’m not an expert in CSS, I asked ChatGPT about your option and I got this, since I want to hide images that start with hide-this-image-, but then have something else. I got this answer:

No, pure CSS does not support wildcard or “starts with” selectors for alt attributes on images.

CSS attribute selectors only support:

  • Exact match: [alt="value"]
  • Contains word: [alt~="value"]
  • Contains substring: [alt*="value"]
  • Starts with: [alt^="value"]
  • Ends with: [alt$="value"]

However, alt^="hide-this-image-" will not work reliably in your example because CSS can’t match the alt attribute of <img> in all browsers when the image is rendered, especially in systems like Discourse where the alt attribute is not necessarily reflected in the DOM in a way CSS can access.

Workaround with CSS (only works in some environments):

.cooked img[alt^="hide-this-image-"] {
  display: none;
}

But again, this may not work consistently in Discourse due to how images are rendered (e.g. through markdown or JS). In that case, you’d need JavaScript.

JavaScript reliable alternative:

document.querySelectorAll('.cooked img[alt^="hide-this-image-"]').forEach(img => {
  img.style.display = 'none';
});

This will work reliably in all environments, including Discourse.

ChatGPT’s solution seems to work:

And Facebook Debugger sees it as the featured image:

Component with the Javascript:

import { apiInitializer } from "discourse/lib/api";

export default apiInitializer((api) => {
  api.onPageChange(() => {
    document
      .querySelectorAll('.cooked img[alt^="featured-image-"]')
      .forEach((img) => {
        const parent = img.closest("div");
        if (parent) {
          parent.style.display = "none";
        } else {
          img.style.display = "none";
        }
      });
  });
});

I noticed that it was keeping some space where the image was supposed to be, so I asked ChatGPT again and it added that it needed to hide the parent container, which in this case it’s the <div> tag.

It’s working great now!

Thanks for that. Added to my notes.