diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json
index 5f66164ac1e2a26ba92fc6d0bfa271d2f173deed..ec4a6d06a665d8b82615b6e0f39f0b42c3086d5a 100644
--- a/.devcontainer/devcontainer.json
+++ b/.devcontainer/devcontainer.json
@@ -25,7 +25,6 @@
     }
   },
   "extensions": [
-    "bierner.lit-html",
     "bmewburn.vscode-intelephense-client",
     "bradlc.vscode-tailwindcss",
     "breezelin.phpstan",
@@ -37,6 +36,7 @@
     "kasik96.latte",
     "mikestead.dotenv",
     "naumovs.color-highlight",
+    "runem.lit-plugin",
     "streetsidesoftware.code-spell-checker",
     "stylelint.vscode-stylelint",
     "wayou.vscode-todo-highlight"
diff --git a/app/Helpers/page_helper.php b/app/Helpers/page_helper.php
index 2c9519a024c9619ef6fe4b62423fb86f57bac704..002e6ae01aebe3098cbe13f30a36d455a834312b 100644
--- a/app/Helpers/page_helper.php
+++ b/app/Helpers/page_helper.php
@@ -20,17 +20,17 @@ if (! function_exists('render_page_links')) {
     {
         $pages = (new PageModel())->findAll();
         $links = anchor(route_to('home'), lang('Common.home'), [
-            'class' => 'px-2 underline hover:no-underline',
+            'class' => 'px-2 py-1 underline hover:no-underline',
         ]);
         $links .= anchor(route_to('credits'), lang('Person.credits'), [
-            'class' => 'px-2 underline hover:no-underline',
+            'class' => 'px-2  py-1 underline hover:no-underline',
         ]);
         $links .= anchor(route_to('map'), lang('Page.map'), [
             'class' => 'px-2 underline hover:no-underline',
         ]);
         foreach ($pages as $page) {
             $links .= anchor($page->link, $page->title, [
-                'class' => 'px-2 underline hover:no-underline',
+                'class' => 'px-2  py-1 underline hover:no-underline',
             ]);
         }
 
diff --git a/app/Language/en/Common.php b/app/Language/en/Common.php
index 28afa79975e7fbb08b595f02b327fbbe44533303..f05e5d6a7c749ed2ca2f01cf34aabb63f0beee7f 100644
--- a/app/Language/en/Common.php
+++ b/app/Language/en/Common.php
@@ -16,6 +16,9 @@ return [
     'more' => 'More',
     'no_data' => 'No data found!',
     'close' => 'Close',
+    'edit' => 'Edit',
+    'copy' => 'Copy',
+    'copied' => 'Copied!',
     'home' => 'Home',
     'explicit' => 'Explicit',
     'mediumDate' => '{0,date,medium}',
diff --git a/app/Language/en/Episode.php b/app/Language/en/Episode.php
index 94f5fc1629d8a1a99c2745c8b6a5f6528aa0ea94..7749b06a2e0ccc9b2e0d331843a08692964bb6e9 100644
--- a/app/Language/en/Episode.php
+++ b/app/Language/en/Episode.php
@@ -67,8 +67,7 @@ return [
         'title' => 'Title',
         'title_hint' =>
             'Should contain a clear and concise episode name. Do not specify the episode or season numbers here.',
-        'slug' => 'Slug',
-        'slug_hint' => 'Used for generating the episode URL.',
+        'permalink' => 'Permalink',
         'season_number' => 'Season',
         'episode_number' => 'Episode',
         'type' => [
diff --git a/app/Language/en/Page.php b/app/Language/en/Page.php
index 86eb345de676bc7e8cf8cda70e5344b6bf091a2b..592b87846447755a83bdd76c16c0abcc67105313 100644
--- a/app/Language/en/Page.php
+++ b/app/Language/en/Page.php
@@ -18,7 +18,7 @@ return [
     'delete' => 'Delete page',
     'form' => [
         'title' => 'Title',
-        'slug' => 'Slug',
+        'permalink' => 'Permalink',
         'content' => 'Content',
         'submit_create' => 'Create page',
         'submit_edit' => 'Save',
diff --git a/app/Language/fr/Common.php b/app/Language/fr/Common.php
index 64997463fb820457028177e67b74942dec9f78a3..2ab2171c708e377953d98f7ab6ac0bb284bfb98c 100644
--- a/app/Language/fr/Common.php
+++ b/app/Language/fr/Common.php
@@ -16,6 +16,9 @@ return [
     'more' => 'Plus',
     'no_data' => 'Aucune donnée trouvée !',
     'close' => 'Fermer',
+    'edit' => 'Modifier',
+    'copy' => 'Copier',
+    'copied' => 'Copié !',
     'home' => 'Accueil',
     'explicit' => 'Explicite',
     'mediumDate' => '{0,date,medium}',
diff --git a/app/Language/fr/Episode.php b/app/Language/fr/Episode.php
index 3a6557872e8e6d74835988f948b27d349f805043..678ed65be255367635fecc112d48b0f5108829ed 100644
--- a/app/Language/fr/Episode.php
+++ b/app/Language/fr/Episode.php
@@ -67,8 +67,7 @@ return [
         'title' => 'Titre',
         'title_hint' =>
             'Doit contenir un titre d’épisode clair et concis. Ne précisez ici aucun numéro de saison ou d’épisode.',
-        'slug' => 'Identifiant',
-        'slug_hint' => 'Utilisé pour générer l’adresse de l’épisode.',
+        'permalink' => 'Lien permanent',
         'season_number' => 'Saison',
         'episode_number' => 'Épisode',
         'type' => [
@@ -144,7 +143,7 @@ return [
         'submit' => 'Publier',
         'submit_edit' => 'Modifier la publication',
         'cancel_publication' => 'Annuler la publication',
-        'message_warning' => 'Vous n’avez pas saisi de message pour l’annonce de votre épisode !',
+        'message_warning' => 'Vous n’avez pas saisi de message pour l’annonce de votre épisode !',
         'message_warning_hint' => 'Ajouter un message augmente l’engagement social, menant à une meilleure visibilité pour votre épisode.',
         'message_warning_submit' => 'Publish quand même',
     ],
diff --git a/app/Language/fr/Page.php b/app/Language/fr/Page.php
index 8bb2ac2d26e44b38efd51e29803a3856082d788f..220b1a73efface001656efd6caff150b85d49969 100644
--- a/app/Language/fr/Page.php
+++ b/app/Language/fr/Page.php
@@ -18,7 +18,7 @@ return [
     'delete' => 'Supprimer la page',
     'form' => [
         'title' => 'Titre',
-        'slug' => 'Identifiant',
+        'permalink' => 'Lien permanent',
         'content' => 'Contenu',
         'submit_create' => 'Créer la page',
         'submit_edit' => 'Enregistrer',
diff --git a/app/Resources/icons/clipboard.svg b/app/Resources/icons/clipboard.svg
new file mode 100644
index 0000000000000000000000000000000000000000..4e4214b22ae95db49d9a4fd2e58ef4cdfa7c6f17
--- /dev/null
+++ b/app/Resources/icons/clipboard.svg
@@ -0,0 +1,6 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
+    <g>
+        <path fill="none" d="M0 0h24v24H0z"/>
+        <path d="M6 4v4h12V4h2.007c.548 0 .993.445.993.993v16.014a.994.994 0 0 1-.993.993H3.993A.994.994 0 0 1 3 21.007V4.993C3 4.445 3.445 4 3.993 4H6zm2-2h8v4H8V2z"/>
+    </g>
+</svg>
diff --git a/app/Resources/js/admin.ts b/app/Resources/js/admin.ts
index 9f9522cb3d82b80f6fd6c773ea9ede0b5b5eed43..ac1ea0704dc54cd36f89c77240c1b92fca8a6789 100644
--- a/app/Resources/js/admin.ts
+++ b/app/Resources/js/admin.ts
@@ -7,6 +7,7 @@ import Dropdown from "./modules/Dropdown";
 import "./modules/markdown-preview";
 import "./modules/markdown-write-preview";
 import MultiSelect from "./modules/MultiSelect";
+import "./modules/permalink-edit";
 import PublishMessageWarning from "./modules/PublishMessageWarning";
 import Select from "./modules/Select";
 import SidebarToggler from "./modules/SidebarToggler";
diff --git a/app/Resources/js/modules/Slugify.ts b/app/Resources/js/modules/Slugify.ts
index 0a84ac3f52feb0edbbec0cf5f582ca7805def5dd..41251722284baaec0c644c2e5aaac9dc47721786 100644
--- a/app/Resources/js/modules/Slugify.ts
+++ b/app/Resources/js/modules/Slugify.ts
@@ -29,6 +29,7 @@ const Slugify = (): void => {
   if (title && slug) {
     title.addEventListener("input", () => {
       slug.value = slugify(title.value);
+      slug.dispatchEvent(new Event("change"));
     });
   }
 };
diff --git a/app/Resources/js/modules/permalink-edit.ts b/app/Resources/js/modules/permalink-edit.ts
new file mode 100644
index 0000000000000000000000000000000000000000..0dff845e50d61e08df3d8a38a6539be6c3eadd49
--- /dev/null
+++ b/app/Resources/js/modules/permalink-edit.ts
@@ -0,0 +1,215 @@
+import "@github/clipboard-copy-element";
+import { css, html, LitElement, TemplateResult } from "lit";
+import {
+  customElement,
+  property,
+  query,
+  queryAssignedNodes,
+  state,
+} from "lit/decorators.js";
+
+@customElement("permalink-edit")
+export class PermalinkEdit extends LitElement {
+  @queryAssignedNodes("domain", true)
+  _domain!: NodeListOf<HTMLSpanElement>;
+
+  @queryAssignedNodes("slug-input", true)
+  _slugInput!: NodeListOf<HTMLInputElement>;
+
+  @query("clipboard-copy")
+  _clipboardCopy!: any;
+
+  @property({ attribute: "edit-label" })
+  editLabel = "Edit";
+
+  @property({ attribute: "copy-label" })
+  copyLabel = "Copy";
+
+  @state()
+  isEditable = false;
+
+  @state()
+  permalink = "";
+
+  @state()
+  slugInputEvents = [
+    {
+      name: "change",
+      onEvent: (): void => {
+        this.setPermalink();
+      },
+    },
+    {
+      name: "focus",
+      onEvent: (): void => {
+        this.editSlug();
+      },
+    },
+    {
+      name: "focusin",
+      onEvent: (event: Event): void => {
+        setTimeout(() => {
+          (event.target as HTMLInputElement).selectionStart = (
+            event.target as HTMLInputElement
+          ).selectionEnd = 10000;
+        }, 0);
+      },
+    },
+    {
+      name: "focusout",
+      onEvent: (): void => {
+        this.stopEdit();
+      },
+    },
+  ];
+
+  connectedCallback(): void {
+    super.connectedCallback();
+  }
+
+  firstUpdated(): void {
+    // set permalink value
+    this.setPermalink();
+
+    this._clipboardCopy.addEventListener("clipboard-copy", (event: Event) => {
+      const notice = (event.target as HTMLDivElement).querySelector(
+        ".notice"
+      ) as HTMLSpanElement;
+      if (notice) {
+        notice.hidden = false;
+        setTimeout(() => {
+          notice.hidden = true;
+        }, 1000);
+      }
+    });
+
+    this._slugInput[0].readOnly = !this.isEditable;
+    this.slugInputEvents.forEach((slugInputEvent) => {
+      this._slugInput[0].addEventListener(
+        slugInputEvent.name,
+        slugInputEvent.onEvent
+      );
+    });
+  }
+
+  disconnectedCallback(): void {
+    super.disconnectedCallback();
+
+    this.slugInputEvents.forEach((slugInputEvent) => {
+      this._slugInput[0].removeEventListener(
+        slugInputEvent.name,
+        slugInputEvent.onEvent
+      );
+    });
+
+    this._clipboardCopy.removeEventListener(
+      "clipboard-copy",
+      (event: Event) => {
+        const notice = (event.target as HTMLDivElement).querySelector(
+          ".notice"
+        ) as HTMLSpanElement;
+        if (notice) {
+          notice.hidden = false;
+          setTimeout(() => {
+            notice.hidden = true;
+          }, 1000);
+        }
+      }
+    );
+  }
+
+  editSlug(): void {
+    this.isEditable = true;
+    this._slugInput[0].readOnly = !this.isEditable;
+    this._slugInput[0].focus();
+  }
+
+  stopEdit(): void {
+    this.isEditable = false;
+    this._slugInput[0].readOnly = !this.isEditable;
+  }
+
+  setPermalink(): void {
+    this.permalink = this._domain[0].innerHTML + this._slugInput[0].value;
+  }
+
+  static styles = css`
+    ::slotted(input[slot="slug-input"][readonly]) {
+      background-color: transparent !important;
+      border-color: transparent !important;
+      padding-left: 0 !important;
+      margin-left: -0.25rem !important;
+      font-weight: 600;
+    }
+
+    ::slotted([slot="domain"]) {
+      margin-right: 0.25rem;
+    }
+
+    button,
+    clipboard-copy {
+      background: transparent;
+      border: none;
+      padding: 0.25rem;
+      cursor: pointer;
+    }
+
+    button svg,
+    clipboard-copy svg {
+      opacity: 0.6;
+      font-size: 1.25rem;
+    }
+
+    button:hover svg,
+    clipboard-copy:hover svg {
+      opacity: 1;
+    }
+
+    clipboard-copy {
+      position: relative;
+    }
+
+    .notice {
+      position: absolute;
+      background-color: black;
+      color: #ffffff;
+      bottom: -1rem;
+      right: 0;
+      font-size: 0.75rem;
+      padding: 0 0.25rem;
+    }
+  `;
+
+  render(): TemplateResult<1> {
+    return html`<slot name="domain"></slot><slot name="slug-input"></slot>${this
+        .isEditable
+        ? ""
+        : html`<button @click="${this.editSlug}" title="${this.editLabel}">
+            <svg
+              viewBox="0 0 24 24"
+              fill="currentColor"
+              width="1em"
+              height="1em"
+            >
+              <g>
+                <path fill="none" d="M0 0h24v24H0z" />
+                <path
+                  d="M7.243 18H3v-4.243L14.435 2.322a1 1 0 0 1 1.414 0l2.829 2.829a1 1 0 0 1 0 1.414L7.243 18zM3 20h18v2H3v-2z"
+                />
+              </g>
+            </svg>
+          </button> `}<clipboard-copy
+        .value="${this.permalink}"
+        title="${this.copyLabel}"
+        ><svg viewBox="0 0 24 24" fill="currentColor" width="1em" height="1em">
+          <g>
+            <path fill="none" d="M0 0h24v24H0z" />
+            <path
+              d="M6 4v4h12V4h2.007c.548 0 .993.445.993.993v16.014a.994.994 0 0 1-.993.993H3.993A.994.994 0 0 1 3 21.007V4.993C3 4.445 3.445 4 3.993 4H6zm2-2h8v4H8V2z"
+            />
+          </g>
+        </svg>
+        <span class="notice" hidden>Copied!</span></clipboard-copy
+      >`;
+  }
+}
diff --git a/app/Views/admin/episode/create.php b/app/Views/admin/episode/create.php
index ef7e2a7d841d86ac22653707757569b7fba5f1ae..7602c1c89cf810daa3914b809043e8ff13f5c740 100644
--- a/app/Views/admin/episode/create.php
+++ b/app/Views/admin/episode/create.php
@@ -77,19 +77,22 @@
 ]) ?>
 
 <?= form_label(
-    lang('Episode.form.slug'),
+    lang('Episode.form.permalink'),
     'slug',
     [],
-    lang('Episode.form.slug_hint'),
 ) ?>
-<?= form_input([
+<permalink-edit class="inline-flex items-center mb-4 text-xs" edit-label="<?= lang('Common.edit') ?>" copy-label="<?= lang('Common.copy') ?>" copied-label="<?= lang('Common.copied') ?>">
+    <span slot="domain"><?= base_url('/@'. $podcast->handle . '/episodes' ) . '/' ?></span>
+    <?= form_input([
     'id' => 'slug',
     'name' => 'slug',
-    'class' => 'form-input mb-4',
+    'class' => 'form-input flex-1 w-0 text-xs',
     'value' => old('slug'),
     'required' => 'required',
     'data-slugify' => 'slug',
-]) ?>
+    'slot' => 'slug-input'
+    ]) ?>
+</permalink-edit>
 
 <div class="flex flex-col mb-4 gap-x-2 gap-y-4 md:flex-row">
     <div class="flex flex-col flex-1">
diff --git a/app/Views/admin/episode/edit.php b/app/Views/admin/episode/edit.php
index 1373b351a6889fd29c646abe21ceedea4ff12dbd..16bb381e818fdd260f444dda5447cd7f3cdde23e 100644
--- a/app/Views/admin/episode/edit.php
+++ b/app/Views/admin/episode/edit.php
@@ -84,19 +84,22 @@
 ]) ?>
 
 <?= form_label(
-    lang('Episode.form.slug'),
+    lang('Episode.form.permalink'),
     'slug',
     [],
-    lang('Episode.form.slug_hint'),
 ) ?>
-<?= form_input([
+<permalink-edit class="inline-flex items-center mb-4 text-xs" edit-label="<?= lang('Common.edit') ?>" copy-label="<?= lang('Common.copy') ?>" copied-label="<?= lang('Common.copied') ?>">
+    <span slot="domain"><?= base_url('/@'. $podcast->handle . '/episodes' ) . '/' ?></span>
+    <?= form_input([
     'id' => 'slug',
     'name' => 'slug',
-    'class' => 'form-input mb-4',
+    'class' => 'form-input flex-1 w-0 text-xs',
     'value' => old('slug', $episode->slug),
     'required' => 'required',
     'data-slugify' => 'slug',
-]) ?>
+    'slot' => 'slug-input'
+    ]) ?>
+</permalink-edit>
 
 <div class="flex flex-col mb-4 gap-x-2 gap-y-4 md:flex-row">
     <div class="flex flex-col flex-1">
diff --git a/app/Views/admin/page/create.php b/app/Views/admin/page/create.php
index 75a1ef7ffb9845d7fe6dc5705209bf417045d3cc..087b08056960310711a1cade47fc773bb2d300f4 100644
--- a/app/Views/admin/page/create.php
+++ b/app/Views/admin/page/create.php
@@ -26,15 +26,23 @@
     'data-slugify' => 'title',
 ]) ?>
 
-<?= form_label(lang('Page.form.slug'), 'slug', ['class' => 'max-w-sm']) ?>
+<?= form_label(
+    lang('Page.form.permalink'),
+    'slug',
+    [],
+) ?>
+<permalink-edit class="inline-flex items-center w-full max-w-sm mb-4 text-xs" edit-label="<?= lang('Common.edit') ?>" copy-label="<?= lang('Common.copy') ?>" copied-label="<?= lang('Common.copied') ?>">
+<span slot="domain" class="flex-shrink-0"><?= base_url('pages' ) . '/' ?></span>
 <?= form_input([
     'id' => 'slug',
     'name' => 'slug',
-    'class' => 'form-input mb-4 max-w-sm',
+    'class' => 'form-input flex-1 w-0 text-xs',
     'value' => old('slug'),
     'required' => 'required',
     'data-slugify' => 'slug',
+    'slot' => 'slug-input',
 ]) ?>
+</permalink-edit>
 
 <div class="mb-4">
     <?= form_label(lang('Page.form.content'), 'content') ?>
diff --git a/app/Views/admin/page/edit.php b/app/Views/admin/page/edit.php
index 7a2a581abc06a896a26dec8347d002dcf6b71ade..4f74d2c3e9f944625cb2b3ddb94ec56df3cb3f9f 100644
--- a/app/Views/admin/page/edit.php
+++ b/app/Views/admin/page/edit.php
@@ -24,17 +24,25 @@
     'value' => old('title', $page->title),
     'required' => 'required',
     'data-slugify' => 'title',
+    'slot' => 'slug-input',
 ]) ?>
 
-<?= form_label(lang('Page.form.slug'), 'slug', ['class' => 'max-w-sm']) ?>
+<?= form_label(
+    lang('Page.form.permalink'),
+    'slug',
+    [],
+) ?>
+<permalink-edit class="inline-flex items-center max-w-sm mb-4 text-xs" edit-label="<?= lang('Common.edit') ?>" copy-label="<?= lang('Common.copy') ?>" copied-label="<?= lang('Common.copied') ?>">
+<span slot="domain" class="flex-shrink-0"><?= base_url('pages') . '/' ?></span>
 <?= form_input([
     'id' => 'slug',
     'name' => 'slug',
-    'class' => 'form-input mb-4 max-w-sm',
+    'class' => 'form-input flex-1 w-0 text-xs',
     'value' => old('slug', $page->slug),
     'required' => 'required',
     'data-slugify' => 'slug',
 ]) ?>
+</permalink-edit>
 
 <div class="mb-4">
     <?= form_label(lang('Page.form.content'), 'content') ?>
diff --git a/package-lock.json b/package-lock.json
index 605508c75853537e5d1475925d2169c4354ea46a..4ad9004a730d941c935c81eb55b8ce5db863da3f 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -9,11 +9,12 @@
       "version": "1.0.0-alpha.80",
       "license": "AGPL-3.0-or-later",
       "dependencies": {
-        "@amcharts/amcharts4": "^4.10.20",
+        "@amcharts/amcharts4": "^4.10.21",
         "@amcharts/amcharts4-geodata": "^4.1.21",
+        "@github/clipboard-copy-element": "^1.1.2",
         "@github/markdown-toolbar-element": "^1.5.1",
         "@github/time-elements": "^3.1.2",
-        "@popperjs/core": "^2.9.2",
+        "@popperjs/core": "^2.9.3",
         "@vime/core": "^5.0.33",
         "choices.js": "^9.0.1",
         "flatpickr": "^4.6.9",
@@ -28,25 +29,23 @@
         "@semantic-release/changelog": "^5.0.1",
         "@semantic-release/exec": "^5.0.0",
         "@semantic-release/git": "^9.0.0",
-        "@semantic-release/gitlab": "^6.2.1",
+        "@semantic-release/gitlab": "^6.2.2",
         "@tailwindcss/forms": "^0.3.3",
         "@tailwindcss/line-clamp": "^0.2.1",
         "@tailwindcss/typography": "^0.4.1",
         "@types/leaflet": "^1.7.5",
         "@types/marked": "^2.0.4",
-        "@types/prosemirror-markdown": "^1.5.2",
-        "@types/prosemirror-view": "^1.18.0",
-        "@typescript-eslint/eslint-plugin": "^4.28.5",
-        "@typescript-eslint/parser": "^4.28.5",
+        "@typescript-eslint/eslint-plugin": "^4.29.1",
+        "@typescript-eslint/parser": "^4.29.1",
         "cross-env": "^7.0.3",
         "cssnano": "^5.0.7",
         "cz-conventional-changelog": "^3.3.0",
-        "eslint": "^7.31.0",
+        "eslint": "^7.32.0",
         "eslint-config-prettier": "^8.3.0",
         "eslint-plugin-prettier": "^3.4.0",
         "husky": "^7.0.1",
         "is-ci": "^3.0.0",
-        "lint-staged": "^11.1.1",
+        "lint-staged": "^11.1.2",
         "lit": "^2.0.0-rc.2",
         "postcss-import": "^14.0.2",
         "postcss-preset-env": "^6.7.0",
@@ -1035,6 +1034,11 @@
       "resolved": "https://registry.npmjs.org/@foliojs-fork/restructure/-/restructure-2.0.2.tgz",
       "integrity": "sha512-59SgoZ3EXbkfSX7b63tsou/SDGzwUEK6MuB5sKqgVK1/XE0fxmpsOb9DQI8LXW3KfGnAjImCGhhEb7uPPAUVNA=="
     },
+    "node_modules/@github/clipboard-copy-element": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/@github/clipboard-copy-element/-/clipboard-copy-element-1.1.2.tgz",
+      "integrity": "sha512-L6CMrcA5we0udafvoSuRCE/Ci/3xrLWKYRGup2IlhxF771bQYsQ2EB1of182pI8ZWM4oxgwzu37+igMeoZjN/A=="
+    },
     "node_modules/@github/markdown-toolbar-element": {
       "version": "1.5.3",
       "resolved": "https://registry.npmjs.org/@github/markdown-toolbar-element/-/markdown-toolbar-element-1.5.3.tgz",
@@ -1941,12 +1945,6 @@
       "integrity": "sha512-1rkryxURpr6aWP7R786/UQOkJ3PcpQiWkAXBmdWc7ryFWqN6a4xfK7BtjXvFBKO9LjQ+MWQSWxYeZX1OApnArA==",
       "dev": true
     },
-    "node_modules/@types/highlight.js": {
-      "version": "9.12.4",
-      "resolved": "https://registry.npmjs.org/@types/highlight.js/-/highlight.js-9.12.4.tgz",
-      "integrity": "sha512-t2szdkwmg2JJyuCM20e8kR2X59WCE5Zkl4bzm1u1Oukjm79zpbiAv+QjnwLnuuV0WHEcX2NgUItu0pAMKuOPww==",
-      "dev": true
-    },
     "node_modules/@types/http-cache-semantics": {
       "version": "4.0.1",
       "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz",
@@ -1977,23 +1975,6 @@
         "@types/geojson": "*"
       }
     },
-    "node_modules/@types/linkify-it": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-3.0.0.tgz",
-      "integrity": "sha512-x9OaQQTb1N2hPZ/LWJsqushexDvz7NgzuZxiRmZio44WPuolTZNHDBCrOxCzRVOMwamJRO2dWax5NbygOf1OTQ==",
-      "dev": true
-    },
-    "node_modules/@types/markdown-it": {
-      "version": "12.0.1",
-      "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-12.0.1.tgz",
-      "integrity": "sha512-mHfT8j/XkPb1uLEfs0/C3se6nd+webC2kcqcy8tgcVr0GDEONv/xaQzAN+aQvkxQXk/jC0Q6mPS+0xhFwRF35g==",
-      "dev": true,
-      "dependencies": {
-        "@types/highlight.js": "^9.7.0",
-        "@types/linkify-it": "*",
-        "@types/mdurl": "*"
-      }
-    },
     "node_modules/@types/marked": {
       "version": "2.0.5",
       "resolved": "https://registry.npmjs.org/@types/marked/-/marked-2.0.5.tgz",
@@ -2009,12 +1990,6 @@
         "@types/unist": "*"
       }
     },
-    "node_modules/@types/mdurl": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-1.0.2.tgz",
-      "integrity": "sha512-eC4U9MlIcu2q0KQmXszyn5Akca/0jrQmwDRgpAMJai7qBWq4amIQhZyNau4VYGtCeALvW1/NtjzJJ567aZxfKA==",
-      "dev": true
-    },
     "node_modules/@types/minimist": {
       "version": "1.2.1",
       "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.1.tgz",
@@ -2033,18 +2008,13 @@
       "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==",
       "dev": true
     },
-    "node_modules/@types/orderedmap": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/@types/orderedmap/-/orderedmap-1.0.0.tgz",
-      "integrity": "sha512-dxKo80TqYx3YtBipHwA/SdFmMMyLCnP+5mkEqN0eMjcTBzHkiiX0ES118DsjDBjvD+zeSsSU9jULTZ+frog+Gw==",
-      "dev": true
-    },
     "node_modules/@types/parse-json": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz",
       "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==",
       "dev": true
     },
+<<<<<<< HEAD
     "node_modules/@types/prosemirror-markdown": {
       "version": "1.5.4",
       "resolved": "https://registry.npmjs.org/@types/prosemirror-markdown/-/prosemirror-markdown-1.5.4.tgz",
@@ -2095,6 +2065,8 @@
         "@types/prosemirror-transform": "*"
       }
     },
+=======
+>>>>>>> c94a163 (feat: replace slug field with interactive permalink component)
     "node_modules/@types/responselike": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz",
@@ -20247,6 +20219,11 @@
       "resolved": "https://registry.npmjs.org/@foliojs-fork/restructure/-/restructure-2.0.2.tgz",
       "integrity": "sha512-59SgoZ3EXbkfSX7b63tsou/SDGzwUEK6MuB5sKqgVK1/XE0fxmpsOb9DQI8LXW3KfGnAjImCGhhEb7uPPAUVNA=="
     },
+    "@github/clipboard-copy-element": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/@github/clipboard-copy-element/-/clipboard-copy-element-1.1.2.tgz",
+      "integrity": "sha512-L6CMrcA5we0udafvoSuRCE/Ci/3xrLWKYRGup2IlhxF771bQYsQ2EB1of182pI8ZWM4oxgwzu37+igMeoZjN/A=="
+    },
     "@github/markdown-toolbar-element": {
       "version": "1.5.3",
       "resolved": "https://registry.npmjs.org/@github/markdown-toolbar-element/-/markdown-toolbar-element-1.5.3.tgz",
@@ -20975,12 +20952,6 @@
       "integrity": "sha512-1rkryxURpr6aWP7R786/UQOkJ3PcpQiWkAXBmdWc7ryFWqN6a4xfK7BtjXvFBKO9LjQ+MWQSWxYeZX1OApnArA==",
       "dev": true
     },
-    "@types/highlight.js": {
-      "version": "9.12.4",
-      "resolved": "https://registry.npmjs.org/@types/highlight.js/-/highlight.js-9.12.4.tgz",
-      "integrity": "sha512-t2szdkwmg2JJyuCM20e8kR2X59WCE5Zkl4bzm1u1Oukjm79zpbiAv+QjnwLnuuV0WHEcX2NgUItu0pAMKuOPww==",
-      "dev": true
-    },
     "@types/http-cache-semantics": {
       "version": "4.0.1",
       "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz",
@@ -21011,23 +20982,6 @@
         "@types/geojson": "*"
       }
     },
-    "@types/linkify-it": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-3.0.0.tgz",
-      "integrity": "sha512-x9OaQQTb1N2hPZ/LWJsqushexDvz7NgzuZxiRmZio44WPuolTZNHDBCrOxCzRVOMwamJRO2dWax5NbygOf1OTQ==",
-      "dev": true
-    },
-    "@types/markdown-it": {
-      "version": "12.0.1",
-      "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-12.0.1.tgz",
-      "integrity": "sha512-mHfT8j/XkPb1uLEfs0/C3se6nd+webC2kcqcy8tgcVr0GDEONv/xaQzAN+aQvkxQXk/jC0Q6mPS+0xhFwRF35g==",
-      "dev": true,
-      "requires": {
-        "@types/highlight.js": "^9.7.0",
-        "@types/linkify-it": "*",
-        "@types/mdurl": "*"
-      }
-    },
     "@types/marked": {
       "version": "2.0.5",
       "resolved": "https://registry.npmjs.org/@types/marked/-/marked-2.0.5.tgz",
@@ -21043,12 +20997,6 @@
         "@types/unist": "*"
       }
     },
-    "@types/mdurl": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-1.0.2.tgz",
-      "integrity": "sha512-eC4U9MlIcu2q0KQmXszyn5Akca/0jrQmwDRgpAMJai7qBWq4amIQhZyNau4VYGtCeALvW1/NtjzJJ567aZxfKA==",
-      "dev": true
-    },
     "@types/minimist": {
       "version": "1.2.1",
       "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.1.tgz",
@@ -21067,18 +21015,13 @@
       "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==",
       "dev": true
     },
-    "@types/orderedmap": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/@types/orderedmap/-/orderedmap-1.0.0.tgz",
-      "integrity": "sha512-dxKo80TqYx3YtBipHwA/SdFmMMyLCnP+5mkEqN0eMjcTBzHkiiX0ES118DsjDBjvD+zeSsSU9jULTZ+frog+Gw==",
-      "dev": true
-    },
     "@types/parse-json": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz",
       "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==",
       "dev": true
     },
+<<<<<<< HEAD
     "@types/prosemirror-markdown": {
       "version": "1.5.4",
       "resolved": "https://registry.npmjs.org/@types/prosemirror-markdown/-/prosemirror-markdown-1.5.4.tgz",
@@ -21129,6 +21072,8 @@
         "@types/prosemirror-transform": "*"
       }
     },
+=======
+>>>>>>> c94a163 (feat: replace slug field with interactive permalink component)
     "@types/responselike": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz",
diff --git a/package.json b/package.json
index 005821c76719d75867ff6eb36db6dfd3edd279d4..b69dcc708c76d6e349974e825852f97ecc515bee 100644
--- a/package.json
+++ b/package.json
@@ -28,10 +28,11 @@
   },
   "dependencies": {
     "@amcharts/amcharts4-geodata": "^4.1.21",
-    "@amcharts/amcharts4": "^4.10.20",
+    "@amcharts/amcharts4": "^4.10.21",
+    "@github/clipboard-copy-element": "^1.1.2",
     "@github/markdown-toolbar-element": "^1.5.1",
     "@github/time-elements": "^3.1.2",
-    "@popperjs/core": "^2.9.2",
+    "@popperjs/core": "^2.9.3",
     "@vime/core": "^5.0.33",
     "choices.js": "^9.0.1",
     "flatpickr": "^4.6.9",
@@ -46,25 +47,23 @@
     "@semantic-release/changelog": "^5.0.1",
     "@semantic-release/exec": "^5.0.0",
     "@semantic-release/git": "^9.0.0",
-    "@semantic-release/gitlab": "^6.2.1",
+    "@semantic-release/gitlab": "^6.2.2",
     "@tailwindcss/forms": "^0.3.3",
     "@tailwindcss/line-clamp": "^0.2.1",
     "@tailwindcss/typography": "^0.4.1",
     "@types/leaflet": "^1.7.5",
     "@types/marked": "^2.0.4",
-    "@types/prosemirror-markdown": "^1.5.2",
-    "@types/prosemirror-view": "^1.18.0",
-    "@typescript-eslint/eslint-plugin": "^4.28.5",
-    "@typescript-eslint/parser": "^4.28.5",
+    "@typescript-eslint/eslint-plugin": "^4.29.1",
+    "@typescript-eslint/parser": "^4.29.1",
     "cross-env": "^7.0.3",
     "cssnano": "^5.0.7",
     "cz-conventional-changelog": "^3.3.0",
     "eslint-config-prettier": "^8.3.0",
     "eslint-plugin-prettier": "^3.4.0",
-    "eslint": "^7.31.0",
+    "eslint": "^7.32.0",
     "husky": "^7.0.1",
     "is-ci": "^3.0.0",
-    "lint-staged": "^11.1.1",
+    "lint-staged": "^11.1.2",
     "lit": "^2.0.0-rc.2",
     "postcss-import": "^14.0.2",
     "postcss-preset-env": "^6.7.0",