diff --git a/src/Twig/ArticleCardCoverExtension.php b/src/Twig/ArticleCardCoverExtension.php
index d2abd44..16b0545 100644
--- a/src/Twig/ArticleCardCoverExtension.php
+++ b/src/Twig/ArticleCardCoverExtension.php
@@ -43,27 +43,23 @@ final class ArticleCardCoverExtension extends AbstractExtension
return [
new TwigFunction('article_card_cover', $this->articleCardCover(...)),
new TwigFunction('article_og_image', $this->articleOgImage(...)),
+ new TwigFunction('site_og_image', $this->siteOgImage(...)),
];
}
/**
- * Absolute URL + whether to emit og:image:width/height (1200×630) for the site default OG JPEG only.
+ * Branded site Open Graph image (home, category lists, base layout default): not tied to any article or author.
*
* @return array{href: string, use_default_dimensions: bool}
*/
- public function articleOgImage(?string $articleImage, ?string $pubkeyHex): array
+ public function siteOgImage(): array
{
- $cover = $this->articleCardCover($articleImage, $pubkeyHex);
- $defaultCover = $this->defaultSiteImageUrl();
$useDefaultDimensions = false;
- $chosen = $cover;
- if ($chosen === $defaultCover) {
- try {
- $chosen = $this->packages->getUrl(self::OG_FALLBACK_PACKAGE_IMAGE);
- $useDefaultDimensions = true;
- } catch (Throwable) {
- $useDefaultDimensions = false;
- }
+ try {
+ $chosen = $this->packages->getUrl(self::OG_FALLBACK_PACKAGE_IMAGE);
+ $useDefaultDimensions = true;
+ } catch (Throwable) {
+ $chosen = $this->defaultSiteImageUrl();
}
return [
@@ -72,6 +68,26 @@ final class ArticleCardCoverExtension extends AbstractExtension
];
}
+ /**
+ * Absolute URL + whether to emit og:image:width/height (1200×630) for the site default OG JPEG only.
+ *
+ * Unlike {@see articleCardCover}, this never uses the author’s Nostr profile picture: crawlers and
+ * in-app link previews should get the article hero or the branded {@see OG_FALLBACK_PACKAGE_IMAGE}.
+ *
+ * @return array{href: string, use_default_dimensions: bool}
+ */
+ public function articleOgImage(?string $articleImage, ?string $_pubkeyHex): array
+ {
+ if ($articleImage !== null && trim($articleImage) !== '') {
+ return [
+ 'href' => $this->absolutizeForOpenGraph(trim($articleImage)),
+ 'use_default_dimensions' => false,
+ ];
+ }
+
+ return $this->siteOgImage();
+ }
+
/**
* Crawlers require absolute https URLs; article/profile images are often https, //, or site-relative.
*/
diff --git a/src/Twig/NostrPathExtension.php b/src/Twig/NostrPathExtension.php
index 0d8a854..735b1e4 100644
--- a/src/Twig/NostrPathExtension.php
+++ b/src/Twig/NostrPathExtension.php
@@ -38,7 +38,7 @@ final class NostrPathExtension extends AbstractExtension
}
/**
- * Lowercase 64-hex pubkey for {@see ArticleCardCoverExtension::articleOgImage} / card cover helpers.
+ * Lowercase 64-hex pubkey for {@see ArticleCardCoverExtension::articleCardCover} and article URLs.
*/
public function pubkeyHexFromNpub(string $npub): string
{
diff --git a/templates/base.html.twig b/templates/base.html.twig
index 245c59e..8819d10 100644
--- a/templates/base.html.twig
+++ b/templates/base.html.twig
@@ -39,8 +39,7 @@
{% block ogtags %}
- {% set _pubkey_hex = pubkey_hex_from_npub(publisher_npub|default('')) %}
- {% set _og = article_og_image(null, _pubkey_hex) %}
+ {% set _og = site_og_image() %}
{% set _og_image = _og.href %}
{% set _og_default_dims = _og.use_default_dimensions %}
diff --git a/templates/home.html.twig b/templates/home.html.twig
index 9016c82..e3ac99c 100644
--- a/templates/home.html.twig
+++ b/templates/home.html.twig
@@ -7,8 +7,7 @@
{% endblock %}
{% block ogtags %}
- {% set _pubkey_hex = pubkey_hex_from_npub(publisher_npub|default('')) %}
- {% set _og = article_og_image(null, _pubkey_hex) %}
+ {% set _og = site_og_image() %}
{% set _og_image = _og.href %}
{% set _og_default_dims = _og.use_default_dimensions %}
diff --git a/templates/pages/category.html.twig b/templates/pages/category.html.twig
index 2d69b7a..a8c363a 100644
--- a/templates/pages/category.html.twig
+++ b/templates/pages/category.html.twig
@@ -11,8 +11,7 @@
{% block ogtags %}
{% set _title = category.title|default('') %}
{% set _summary = category.summary|default('')|striptags|u.truncate(159, '…') %}
- {% set _pubkey_hex = pubkey_hex_from_npub(publisher_npub|default('')) %}
- {% set _og = article_og_image(null, _pubkey_hex) %}
+ {% set _og = site_og_image() %}
{% set _og_image = _og.href %}
{% set _og_default_dims = _og.use_default_dimensions %}
{% set _is_articles_route = app.request.attributes.get('_route') == 'articles' %}