diff --git a/addons/website/i18n/website.pot b/addons/website/i18n/website.pot
index 891c277be713164250a203ee5a8e36e55ccfe031..8915466845ddf3de55a35945fe6b63a152394d2a 100644
--- a/addons/website/i18n/website.pot
+++ b/addons/website/i18n/website.pot
@@ -7195,6 +7195,16 @@ msgstr ""
 
 #. module: website
 #. openerp-web
+#: code:addons/website/static/src/js/editor/snippets.options.js:0
+#, python-format
+msgid ""
+"This font already exists, you can only add it as a local font to replace the"
+" server version."
+msgstr ""
+
+#. module: website
+#. openerp-web
+#: code:addons/website/static/src/js/editor/snippets.options.js:0
 #: code:addons/website/static/src/xml/website.editor.xml:0
 #, python-format
 msgid "This font is hosted and served to your visitors by Google servers"
diff --git a/addons/website/static/src/js/editor/snippets.options.js b/addons/website/static/src/js/editor/snippets.options.js
index 2c271c7e36e58837988198c28b8b85bbf1fce8f0..4cbd56592a45d2933edc6df9200ad6f44e9fec94 100644
--- a/addons/website/static/src/js/editor/snippets.options.js
+++ b/addons/website/static/src/js/editor/snippets.options.js
@@ -91,25 +91,48 @@ const FontFamilyPickerUserValueWidget = SelectUserValueWidget.extend({
     start: async function () {
         const style = window.getComputedStyle(document.documentElement);
         const nbFonts = parseInt(weUtils.getCSSVariableValue('number-of-fonts', style));
+        // User fonts served by google server.
         const googleFontsProperty = weUtils.getCSSVariableValue('google-fonts', style);
         this.googleFonts = googleFontsProperty ? googleFontsProperty.split(/\s*,\s*/g) : [];
         this.googleFonts = this.googleFonts.map(font => font.substring(1, font.length - 1)); // Unquote
+        // Local user fonts.
         const googleLocalFontsProperty = weUtils.getCSSVariableValue('google-local-fonts', style);
         this.googleLocalFonts = googleLocalFontsProperty ?
             googleLocalFontsProperty.slice(1, -1).split(/\s*,\s*/g) : [];
+        // If a same font exists both remotely and locally, we remove the remote
+        // font to prioritize the local font. The remote one will never be
+        // displayed or loaded as long as the local one exists.
+        this.googleFonts = this.googleFonts.filter(font => {
+            const localFonts = this.googleLocalFonts.map(localFont => localFont.split(":")[0]);
+            return localFonts.indexOf(`'${font}'`) === -1;
+        });
+        this.allFonts = [];
 
         await this._super(...arguments);
 
         const fontEls = [];
         const methodName = this.el.dataset.methodName || 'customizeWebsiteVariable';
         const variable = this.el.dataset.variable;
+        const themeFontsNb = nbFonts - (this.googleLocalFonts.length + this.googleFonts.length);
         _.times(nbFonts, fontNb => {
             const realFontNb = fontNb + 1;
             const fontEl = document.createElement('we-button');
             fontEl.classList.add(`o_we_option_font_${realFontNb}`);
             fontEl.dataset.variable = variable;
             fontEl.dataset[methodName] = weUtils.getCSSVariableValue(`font-number-${realFontNb}`, style);
+            const font = weUtils.getCSSVariableValue(`font-number-${realFontNb}`, style);
+            this.allFonts.push(font);
+            fontEl.dataset[methodName] = font;
             fontEl.dataset.font = realFontNb;
+            if (realFontNb <= themeFontsNb) {
+                // Add the "cloud" icon next to the theme's default fonts
+                // because they are served by Google.
+                fontEl.appendChild(Object.assign(document.createElement('i'), {
+                    role: 'button',
+                    className: 'text-info ml-2 fa fa-cloud',
+                    title: _t("This font is hosted and served to your visitors by Google servers"),
+                }));
+            }
             fontEls.push(fontEl);
             this.menuEl.appendChild(fontEl);
         });
@@ -209,6 +232,20 @@ const FontFamilyPickerUserValueWidget = SelectUserValueWidget.extend({
 
                         const font = m[1].replace(/\+/g, ' ');
                         const googleFontServe = dialog.el.querySelector('#google_font_serve').checked;
+                        const fontName = `'${font}'`;
+                        // If the font already exists, it will only be added if
+                        // the user chooses to add it locally when it is already
+                        // imported from the Google Fonts server.
+                        const fontExistsLocally = this.googleLocalFonts.some(localFont => localFont.split(':')[0] === fontName);
+                        const fontExistsOnServer = this.allFonts.includes(fontName);
+                        const preventFontAddition = fontExistsLocally || (fontExistsOnServer && googleFontServe);
+                        if (preventFontAddition) {
+                            inputEl.classList.add('is-invalid');
+                            // Show custom validity error message.
+                            inputEl.setCustomValidity(_t("This font already exists, you can only add it as a local font to replace the server version."));
+                            inputEl.reportValidity();
+                            return;
+                        }
                         if (googleFontServe) {
                             this.googleFonts.push(font);
                         } else {
@@ -253,7 +290,8 @@ const FontFamilyPickerUserValueWidget = SelectUserValueWidget.extend({
         let googleFontName;
         if (isLocalFont) {
             const googleFont = this.googleLocalFonts[googleFontIndex].split(':');
-            googleFontName = googleFont[0];
+            // Remove double quotes
+            googleFontName = googleFont[0].substring(1, googleFont[0].length - 1);
             values['delete-font-attachment-id'] = googleFont[1];
             this.googleLocalFonts.splice(googleFontIndex, 1);
         } else {
diff --git a/addons/website/static/src/scss/secondary_variables.scss b/addons/website/static/src/scss/secondary_variables.scss
index 0f85a3fc94b7e1b3ea86978d3c0586cf75fd990e..967201554fb2d2848c02ea383b0f8d6ab527c331 100644
--- a/addons/website/static/src/scss/secondary_variables.scss
+++ b/addons/website/static/src/scss/secondary_variables.scss
@@ -172,6 +172,9 @@ $o-we-auto-contrast-exclusions: join($o-we-auto-contrast-exclusions, map-keys(o-
 
 // Add locally hosted google fonts
 @each $font-name, $font-attach-id in (o-website-value('google-local-fonts') or ()) {
+    // If a font exists both remotely and locally, we remove the remote font to
+    // prioritize the local font.
+    $o-theme-font-configs: map-remove($o-theme-font-configs, $font-name);
     $o-theme-font-configs: map-merge($o-theme-font-configs, (
         $font-name: (
             'family': (quote($font-name), sans-serif),
diff --git a/addons/website/static/src/xml/website.editor.xml b/addons/website/static/src/xml/website.editor.xml
index 571f84c659d0d213b20ddce4c072f1b9ef8b78ef..c46aa1aa2d3e7f2e0dbfc60db425d41aae7ce1a6 100644
--- a/addons/website/static/src/xml/website.editor.xml
+++ b/addons/website/static/src/xml/website.editor.xml
@@ -78,7 +78,7 @@
         <p>Adding a font requires a reload of the page. This will save all your changes.</p>
     </div>
     <t t-name="website.delete_google_font_btn">
-        <i t-if="!local" role="button" class="text-info ms-2 fa fa-cloud" title="This font is hosted and served to your visitors by Google servers"/>
+        <i t-if="!local" role="button" class="text-info ml-2 fa fa-cloud" title="This font is hosted and served to your visitors by Google servers"/>
         <t t-set="delete_font_title">Delete this font</t>
         <i role="button"
            class="text-danger ml-2 fa fa-trash-o o_we_delete_google_font_btn"