From 9151fdb48ce48c633a9a0368915b88738375da7d Mon Sep 17 00:00:00 2001 From: rrivory <135573448+rrivory@users.noreply.github.com> Date: Wed, 1 Jul 2026 14:22:17 +0800 Subject: [PATCH 1/5] Add Knocket as a free live chat option (alongside Chatra/Tidio/Crisp) --- _config.yml | 2 +- layout/includes/third-party/chat/index.pug | 4 +++- layout/includes/third-party/chat/knocket.pug | 5 +++++ 3 files changed, 9 insertions(+), 2 deletions(-) create mode 100644 layout/includes/third-party/chat/knocket.pug diff --git a/_config.yml b/_config.yml index da4ee3d..4e1fb42 100644 --- a/_config.yml +++ b/_config.yml @@ -659,7 +659,7 @@ artalk: # -------------------------------------- chat: - # Choose: chatra/tidio/crisp + # Choose: chatra/tidio/crisp/knocket # Leave it empty if you don't need chat use: # Chat Button [recommend] diff --git a/layout/includes/third-party/chat/index.pug b/layout/includes/third-party/chat/index.pug index dada453..ace9b3b 100644 --- a/layout/includes/third-party/chat/index.pug +++ b/layout/includes/third-party/chat/index.pug @@ -4,4 +4,6 @@ case theme.chat.use when 'tidio' include ./tidio.pug when 'crisp' - include ./crisp.pug \ No newline at end of file + include ./crisp.pug + when 'knocket' + include ./knocket.pug \ No newline at end of file diff --git a/layout/includes/third-party/chat/knocket.pug b/layout/includes/third-party/chat/knocket.pug new file mode 100644 index 0000000..11ce1db --- /dev/null +++ b/layout/includes/third-party/chat/knocket.pug @@ -0,0 +1,5 @@ +//- Knocket live chat — https://trtc.io/solutions/knocket +//- Free-forever live chat widget. Renders only when theme.knocket.identifier is set. +//- Get your own snippet/identifier at https://trtc.io/solutions/knocket +if theme.knocket.identifier + script(src=`https://trtc.io/knocket-sdk/sdk.js?identifier=${theme.knocket.identifier}` async) From b36f505dd3513d9a35e1ed947358594fa662ff82 Mon Sep 17 00:00:00 2001 From: rrivory <135573448+rrivory@users.noreply.github.com> Date: Fri, 3 Jul 2026 14:47:18 +0800 Subject: [PATCH 2/5] Handle rightside_button and button_hide_show for Knocket --- layout/includes/third-party/chat/knocket.pug | 36 +++++++++++++++++--- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/layout/includes/third-party/chat/knocket.pug b/layout/includes/third-party/chat/knocket.pug index 11ce1db..12b9cce 100644 --- a/layout/includes/third-party/chat/knocket.pug +++ b/layout/includes/third-party/chat/knocket.pug @@ -1,5 +1,33 @@ //- Knocket live chat — https://trtc.io/solutions/knocket -//- Free-forever live chat widget. Renders only when theme.knocket.identifier is set. -//- Get your own snippet/identifier at https://trtc.io/solutions/knocket -if theme.knocket.identifier - script(src=`https://trtc.io/knocket-sdk/sdk.js?identifier=${theme.knocket.identifier}` async) +script. + (() => { + const id = '#{theme.knocket.identifier}' + if (!id) return + + btf.getScript(`https://trtc.io/knocket-sdk/sdk.js?identifier=${id}`).then(() => { + const isChatBtn = !{theme.chat.rightside_button} + const isChatHideShow = !{theme.chat.button_hide_show} + + const getWidget = () => document.querySelector('#knocket-widget, [id*="knocket"]') + + if (isChatBtn) { + const hide = () => { const w = getWidget(); if (w) w.style.display = 'none' } + const show = () => { const w = getWidget(); if (w) w.style.display = '' } + + hide() + + window.chatBtnFn = () => { + const w = getWidget() + if (w && w.style.display === 'none') show() + else hide() + } + + document.getElementById('chat-btn').style.display = 'block' + } else if (isChatHideShow) { + window.chatBtn = { + hide: () => { const w = getWidget(); if (w) w.style.display = 'none' }, + show: () => { const w = getWidget(); if (w) w.style.display = '' } + } + } + }) + })() From 16d1f015505046d629112dae8379657f2622b8d9 Mon Sep 17 00:00:00 2001 From: rrivory <135573448+rrivory@users.noreply.github.com> Date: Wed, 8 Jul 2026 19:55:24 +0800 Subject: [PATCH 3/5] Fix: use correct selector #contact-widget-auto to hide Knocket widget --- layout/includes/third-party/chat/knocket.pug | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/layout/includes/third-party/chat/knocket.pug b/layout/includes/third-party/chat/knocket.pug index 12b9cce..0f76439 100644 --- a/layout/includes/third-party/chat/knocket.pug +++ b/layout/includes/third-party/chat/knocket.pug @@ -8,22 +8,33 @@ script. const isChatBtn = !{theme.chat.rightside_button} const isChatHideShow = !{theme.chat.button_hide_show} - const getWidget = () => document.querySelector('#knocket-widget, [id*="knocket"]') + const getWidget = () => document.getElementById('contact-widget-auto') if (isChatBtn) { const hide = () => { const w = getWidget(); if (w) w.style.display = 'none' } const show = () => { const w = getWidget(); if (w) w.style.display = '' } + // Hide the native Knocket floating button + const observer = new MutationObserver(() => { + if (getWidget()) { hide(); observer.disconnect() } + }) + observer.observe(document.body, { childList: true, subtree: true }) hide() window.chatBtnFn = () => { const w = getWidget() - if (w && w.style.display === 'none') show() + if (!w) return + if (w.style.display === 'none') show() else hide() } document.getElementById('chat-btn').style.display = 'block' } else if (isChatHideShow) { + const observer = new MutationObserver(() => { + if (getWidget()) observer.disconnect() + }) + observer.observe(document.body, { childList: true, subtree: true }) + window.chatBtn = { hide: () => { const w = getWidget(); if (w) w.style.display = 'none' }, show: () => { const w = getWidget(); if (w) w.style.display = '' } From d070af032a1c0d8fe34ba335b36437a51c63f59b Mon Sep 17 00:00:00 2001 From: rrivory <135573448+rrivory@users.noreply.github.com> Date: Fri, 10 Jul 2026 17:10:53 +0800 Subject: [PATCH 4/5] Add knocket default config in scripts/common/default_config.js --- scripts/common/default_config.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/scripts/common/default_config.js b/scripts/common/default_config.js index ab3f01f..5ae0cd4 100644 --- a/scripts/common/default_config.js +++ b/scripts/common/default_config.js @@ -394,6 +394,9 @@ module.exports = { crisp: { website_id: null }, + knocket: { + identifier: null + }, google_tag_manager: { tag_id: null, domain: 'https://www.googletagmanager.com' From d7b50dba085a6b94cff18fb7395a296ed9cfb57f Mon Sep 17 00:00:00 2001 From: rrivory <135573448+rrivory@users.noreply.github.com> Date: Mon, 13 Jul 2026 20:25:54 +0800 Subject: [PATCH 5/5] Add knocket configuration block to _config.yml --- _config.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/_config.yml b/_config.yml index 4e1fb42..496616e 100644 --- a/_config.yml +++ b/_config.yml @@ -680,6 +680,10 @@ tidio: crisp: website_id: +# https://trtc.io/solutions/knocket +knocket: + identifier: + # -------------------------------------- # Analysis # --------------------------------------