diff --git a/components/parts/common/post-sharing.php b/components/parts/common/post-sharing.php
new file mode 100644
index 00000000..ba85b7d3
--- /dev/null
+++ b/components/parts/common/post-sharing.php
@@ -0,0 +1,41 @@
+
+
+
+
+
+
+
+
+
diff --git a/languages/beapi-frontend-framework.pot b/languages/beapi-frontend-framework.pot
index 6d9bc44c..7de87f97 100644
--- a/languages/beapi-frontend-framework.pot
+++ b/languages/beapi-frontend-framework.pot
@@ -9,7 +9,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"POT-Creation-Date: 2026-05-07T14:30:39+00:00\n"
+"POT-Creation-Date: 2026-09-18T09:57:30+00:00\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"X-Generator: WP-CLI 2.12.0\n"
"X-Domain: beapi-frontend-framework\n"
@@ -39,6 +39,26 @@ msgstr ""
msgid "Breadcrumb"
msgstr ""
+#: components/parts/common/post-sharing.php:25
+msgid "Link copied!"
+msgstr ""
+
+#: components/parts/common/post-sharing.php:26
+msgid "Unable to copy the link"
+msgstr ""
+
+#: components/parts/common/post-sharing.php:27
+msgid "Unable to share"
+msgstr ""
+
+#: components/parts/common/post-sharing.php:33
+msgid "Copy link"
+msgstr ""
+
+#: components/parts/common/post-sharing.php:37
+msgid "Share"
+msgstr ""
+
#: footer.php:2
msgid "Footer"
msgstr ""
@@ -92,6 +112,10 @@ msgstr ""
msgid "Close menu"
msgstr ""
+#: inc/Helpers/Formatting/Datetime.php:53
+msgid "Published on"
+msgstr ""
+
#: inc/Helpers/Formatting/Link.php:144
msgid "New window"
msgstr ""
@@ -120,46 +144,28 @@ msgstr ""
msgid "Share by email"
msgstr ""
-#: inc/Services/Editor.php:144
+#: inc/Services/Editor.php:168
msgid "Small"
msgstr ""
-#: inc/Services/Editor.php:152
+#: inc/Services/Editor.php:176
msgid "Large"
msgstr ""
-#: inc/Services/Editor.php:160
+#: inc/Services/Editor.php:184
msgid "Huge"
msgstr ""
#. translators: %s: heading number
-#: inc/Services/Editor.php:168
+#: inc/Services/Editor.php:192
#, php-format
msgid "Style H%s"
msgstr ""
-#: inc/Services/Editor_Patterns.php:40
+#: inc/Services/Editor_Patterns.php:45
msgid "Common"
msgstr ""
-#. translators: %s: file name.
-#: inc/Services/Editor_Patterns.php:125
-#, php-format
-msgid "Could not register file \"%s\" as a block pattern (\"Slug\" field missing)"
-msgstr ""
-
-#. translators: %1s: file name; %2s: slug value found.
-#: inc/Services/Editor_Patterns.php:138
-#, php-format
-msgid "Could not register file \"%1$s\" as a block pattern (invalid slug \"%2$s\")"
-msgstr ""
-
-#. translators: %1s: file name; %2s: slug value found.
-#: inc/Services/Editor_Patterns.php:155
-#, php-format
-msgid "Could not register file \"%s\" as a block pattern (\"Title\" field missing)"
-msgstr ""
-
#: inc/Services/Menu.php:37
msgid "Main menu"
msgstr ""
diff --git a/languages/fr_FR.mo b/languages/fr_FR.mo
index c62c0ed6..c22b928a 100644
Binary files a/languages/fr_FR.mo and b/languages/fr_FR.mo differ
diff --git a/languages/fr_FR.po b/languages/fr_FR.po
index 4f5562c0..2b28850f 100644
--- a/languages/fr_FR.po
+++ b/languages/fr_FR.po
@@ -5,8 +5,8 @@ msgstr ""
"Project-Id-Version: Be API Frontend Framework 1.0.0\n"
"Report-Msgid-Bugs-To: https://wordpress.org/support/theme/beapi-frontend-"
"framework\n"
-"POT-Creation-Date: 2026-05-07T14:30:39+00:00\n"
-"PO-Revision-Date: 2026-05-07 16:41+0200\n"
+"POT-Creation-Date: 2026-09-18T09:57:30+00:00\n"
+"PO-Revision-Date: 2026-09-18 12:00+0200\n"
"Last-Translator: \n"
"Language-Team: \n"
"Language: fr\n"
@@ -42,6 +42,26 @@ msgstr ""
msgid "Breadcrumb"
msgstr "Fil d’ariane"
+#: components/parts/common/post-sharing.php:25
+msgid "Link copied!"
+msgstr "Lien copié !"
+
+#: components/parts/common/post-sharing.php:26
+msgid "Unable to copy the link"
+msgstr "Impossible de copier le lien"
+
+#: components/parts/common/post-sharing.php:27
+msgid "Unable to share"
+msgstr "Impossible de partager"
+
+#: components/parts/common/post-sharing.php:33
+msgid "Copy link"
+msgstr "Copier le lien"
+
+#: components/parts/common/post-sharing.php:37
+msgid "Share"
+msgstr "Partager"
+
#: footer.php:2
msgid "Footer"
msgstr "Pied de Page"
@@ -94,6 +114,10 @@ msgstr "Ouvrir le menu"
msgid "Close menu"
msgstr "Fermer le menu"
+#: inc/Helpers/Formatting/Datetime.php:53
+msgid "Published on"
+msgstr "Publié le"
+
#: inc/Helpers/Formatting/Link.php:144
msgid "New window"
msgstr "Nouvelle fenêtre"
@@ -122,55 +146,28 @@ msgstr "Partager sur Bluesky"
msgid "Share by email"
msgstr "Partager par email"
-#: inc/Services/Editor.php:144
+#: inc/Services/Editor.php:168
msgid "Small"
msgstr "Petit"
-#: inc/Services/Editor.php:152
+#: inc/Services/Editor.php:176
msgid "Large"
msgstr "Grand"
-#: inc/Services/Editor.php:160
+#: inc/Services/Editor.php:184
msgid "Huge"
msgstr "Très grand"
#. translators: %s: heading number
-#: inc/Services/Editor.php:168
+#: inc/Services/Editor.php:192
#, php-format
msgid "Style H%s"
msgstr ""
-#: inc/Services/Editor_Patterns.php:40
+#: inc/Services/Editor_Patterns.php:45
msgid "Common"
msgstr "Général"
-#. translators: %s: file name.
-#: inc/Services/Editor_Patterns.php:125
-#, php-format
-msgid ""
-"Could not register file \"%s\" as a block pattern (\"Slug\" field missing)"
-msgstr ""
-"Impossible de déclarer la composition de blocs à partir du fichier \"%s\" "
-"(Le champ \"Slug\" est manquant)"
-
-#. translators: %1s: file name; %2s: slug value found.
-#: inc/Services/Editor_Patterns.php:138
-#, php-format
-msgid ""
-"Could not register file \"%1$s\" as a block pattern (invalid slug \"%2$s\")"
-msgstr ""
-"Impossible de déclarer la composition de blocs à partir du fichier \"%1$s\" "
-"(Le slug \"%2$s\" n'est pas valide)"
-
-#. translators: %1s: file name; %2s: slug value found.
-#: inc/Services/Editor_Patterns.php:155
-#, php-format
-msgid ""
-"Could not register file \"%s\" as a block pattern (\"Title\" field missing)"
-msgstr ""
-"Impossible de déclarer la composition de blocs à partir du fichier \"%s\" "
-"(Le champ \"Title\" est manquant)"
-
#: inc/Services/Menu.php:37
msgid "Main menu"
msgstr "Menu principal"
@@ -264,6 +261,29 @@ msgctxt "Space size name"
msgid "lg (64px)"
msgstr ""
+#, php-format
+#~ msgid ""
+#~ "Could not register file \"%s\" as a block pattern (\"Slug\" field missing)"
+#~ msgstr ""
+#~ "Impossible de déclarer la composition de blocs à partir du fichier \"%s\" "
+#~ "(Le champ \"Slug\" est manquant)"
+
+#, php-format
+#~ msgid ""
+#~ "Could not register file \"%1$s\" as a block pattern (invalid slug "
+#~ "\"%2$s\")"
+#~ msgstr ""
+#~ "Impossible de déclarer la composition de blocs à partir du fichier "
+#~ "\"%1$s\" (Le slug \"%2$s\" n'est pas valide)"
+
+#, php-format
+#~ msgid ""
+#~ "Could not register file \"%s\" as a block pattern (\"Title\" field "
+#~ "missing)"
+#~ msgstr ""
+#~ "Impossible de déclarer la composition de blocs à partir du fichier \"%s\" "
+#~ "(Le champ \"Title\" est manquant)"
+
#~ msgid "Dark"
#~ msgstr "Sombre"
diff --git a/src/img/icons/sprite/check-circle.svg b/src/img/icons/sprite/check-circle.svg
new file mode 100644
index 00000000..51a0b78e
--- /dev/null
+++ b/src/img/icons/sprite/check-circle.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/img/icons/sprite/link.svg b/src/img/icons/sprite/link.svg
new file mode 100644
index 00000000..1ba22c65
--- /dev/null
+++ b/src/img/icons/sprite/link.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/img/icons/sprite/logo-beapi.svg b/src/img/icons/sprite/logo-beapi.svg
deleted file mode 100644
index 5cf0fca4..00000000
--- a/src/img/icons/sprite/logo-beapi.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/src/img/icons/sprite/share.svg b/src/img/icons/sprite/share.svg
new file mode 100644
index 00000000..9adcdcc2
--- /dev/null
+++ b/src/img/icons/sprite/share.svg
@@ -0,0 +1 @@
+
diff --git a/src/js/classes/PostSharing.js b/src/js/classes/PostSharing.js
new file mode 100644
index 00000000..3f32cec9
--- /dev/null
+++ b/src/js/classes/PostSharing.js
@@ -0,0 +1,148 @@
+import AbstractDomElement from './AbstractDomElement'
+
+/**
+ * Post sharing — copy link (desktop) and native share (mobile).
+ * Button visibility is handled in CSS.
+ */
+class PostSharing extends AbstractDomElement {
+ constructor(element, options) {
+ const instance = super(element, options)
+
+ // avoid double init :
+ if (!instance.isNewInstance()) {
+ return instance
+ }
+
+ const el = this._element
+ const copyButton = el.querySelector('[data-action="copy"]')
+ const shareButton = el.querySelector('[data-action="share"]')
+ const status = el.querySelector('.post-sharing__status')
+
+ if (!el.dataset.url || !copyButton || !status) {
+ return instance
+ }
+
+ this._copyButton = copyButton
+ this._shareButton = shareButton
+ this._status = status
+
+ copyButton.addEventListener('click', onClickCopy.bind(this))
+
+ // No Web Share API: CSS shows the copy button as mobile fallback.
+ if (!shareButton || typeof navigator.share !== 'function') {
+ el.classList.add('post-sharing--no-native-share')
+ return instance
+ }
+
+ shareButton.addEventListener('click', onClickShare.bind(this))
+
+ return instance
+ }
+}
+
+// ----
+// defaults
+// ----
+
+PostSharing.defaults = {
+ resetDelay: 3000,
+}
+
+// ----
+// utils
+// ----
+
+/**
+ * Announce a message to screen readers, then clear it.
+ *
+ * @param {HTMLElement} el Status element.
+ * @param {string} message Message to announce.
+ * @param {number} delay Duration before clearing (ms).
+ */
+function showTemporaryMessage(el, message, delay) {
+ // Keep the live region in the accessibility tree (no `hidden`):
+ // `sr-only` already hides it visually; toggling `hidden` would block announcements.
+ el.textContent = message
+
+ window.setTimeout(() => {
+ el.textContent = ''
+ }, delay)
+}
+
+/**
+ * Swap the copy button label and icon, then restore the default state.
+ *
+ * @param {HTMLButtonElement} copyButton
+ * @param {HTMLElement} statusEl
+ * @param {string} copiedLabel
+ * @param {number} delay
+ */
+function showCopySuccess(copyButton, statusEl, copiedLabel, delay) {
+ const labelEl = copyButton.querySelector('.post-sharing__label')
+
+ if (!labelEl || copyButton.classList.contains('is-copied')) {
+ return
+ }
+
+ const originalLabel = labelEl.textContent
+
+ labelEl.textContent = copiedLabel
+ copyButton.classList.add('is-copied')
+ showTemporaryMessage(statusEl, copiedLabel, delay)
+
+ window.setTimeout(() => {
+ labelEl.textContent = originalLabel
+ copyButton.classList.remove('is-copied')
+ }, delay)
+}
+
+// ----
+// events
+// ----
+
+async function onClickCopy() {
+ const { url, copiedLabel, errorCopy } = this._element.dataset
+ const { resetDelay } = this._settings
+
+ try {
+ await navigator.clipboard.writeText(url)
+ showCopySuccess(this._copyButton, this._status, copiedLabel, resetDelay)
+ } catch {
+ showTemporaryMessage(this._status, errorCopy, resetDelay)
+ }
+}
+
+async function onClickShare() {
+ const { url, title, errorShare } = this._element.dataset
+ const { resetDelay } = this._settings
+
+ try {
+ const shareData = { url }
+
+ if (title) {
+ shareData.title = title
+ }
+
+ if (navigator.canShare?.(shareData) === false) {
+ showTemporaryMessage(this._status, errorShare, resetDelay)
+ return
+ }
+
+ await navigator.share(shareData)
+ } catch (error) {
+ // User dismissed the native share sheet — not an error.
+ if (error?.name !== 'AbortError') {
+ showTemporaryMessage(this._status, errorShare, resetDelay)
+ }
+ }
+}
+
+// ----
+// init
+// ----
+PostSharing.init('.post-sharing')
+
+// ----
+// export
+// ----
+export default PostSharing
diff --git a/src/js/index.js b/src/js/index.js
index b2cfa361..dc67e40f 100644
--- a/src/js/index.js
+++ b/src/js/index.js
@@ -3,3 +3,4 @@ import './classes/ScrollDirection'
import './classes/ButtonSeoClick'
import './classes/Header'
import './classes/Animation'
+import './classes/PostSharing'
diff --git a/src/scss/05-components/_post-sharing.scss b/src/scss/05-components/_post-sharing.scss
new file mode 100644
index 00000000..89c6020e
--- /dev/null
+++ b/src/scss/05-components/_post-sharing.scss
@@ -0,0 +1,97 @@
+@use "../01-abstract/theme-json" as *;
+@use "../02-tools/m-breakpoint" as *;
+@use "../02-tools/m-hover" as *;
+
+/**
+ * Post sharing — copy link (desktop) / native share (mobile).
+ * Without navigator.share, copy is also shown on small screens as fallback.
+ */
+
+.post-sharing {
+ $el: &;
+
+ &__actions {
+ display: flex;
+ flex-wrap: wrap;
+ align-items: center;
+ }
+
+ &__button {
+ --post-sharing-color: #{$settings-color-black};
+ --post-sharing-bg: #{$settings-color-grey-100};
+ --post-sharing-hover-color: #{$settings-color-black};
+ --post-sharing-hover-bg: #{$settings-color-grey-200};
+ --post-sharing-icon-size: 20px;
+
+ display: inline-flex;
+ gap: 8px;
+ align-items: center;
+ padding: 8px 12px;
+ color: var(--post-sharing-color);
+ cursor: pointer;
+ background-color: var(--post-sharing-bg);
+ border: 0;
+ border-radius: 50px;
+ transition: background-color .3s ease, color .3s ease;
+ appearance: none;
+
+ @include hover {
+ color: var(--post-sharing-hover-color);
+ background-color: var(--post-sharing-hover-bg);
+ }
+
+ &--copy {
+ &.is-copied {
+ #{$el}__icon--copy {
+ display: none;
+ }
+
+ #{$el}__icon--check {
+ display: block;
+ }
+ }
+
+ @include breakpoints(sm) {
+ display: inline-flex;
+ }
+
+ @include breakpoints(sm, max) {
+ display: none;
+ }
+ }
+
+ &--share {
+ @include breakpoints(sm) {
+ display: none;
+ }
+
+ @include breakpoints(sm, max) {
+ display: inline-flex;
+ }
+ }
+ }
+
+ &__icon {
+ width: var(--post-sharing-icon-size);
+ height: var(--post-sharing-icon-size);
+
+ &--check {
+ display: none;
+ }
+ }
+
+ // Fallback when Web Share API is unavailable: show copy on small screens.
+ &--no-native-share {
+ #{$el}__button--share {
+ @include breakpoints(sm, max) {
+ display: none;
+ }
+ }
+
+ #{$el}__button--copy {
+ @include breakpoints(sm, max) {
+ display: inline-flex;
+ }
+ }
+ }
+}
diff --git a/src/scss/style.scss b/src/scss/style.scss
index 486bce0a..cd29f267 100644
--- a/src/scss/style.scss
+++ b/src/scss/style.scss
@@ -49,6 +49,7 @@ variables.$entry-file-name: "style";
@use "05-components/btn";
@use "05-components/searchform";
@use "05-components/skip-links";
+@use "05-components/post-sharing";
/**
* Gutenberg