Skip to content

Commit 55d5ba0

Browse files
authored
feat: [DRO-66] Add configurable Made with Nooxy header badge (#51)
* feat: [DRO-66] Add configurable Made with Nooxy header badge * update: nooxy version in examples * docs: add nooxy configuration section to README
1 parent e0d6c8d commit 55d5ba0

8 files changed

Lines changed: 55 additions & 10 deletions

File tree

README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,16 @@ pageMetadata: {
274274
}
275275
```
276276

277+
### Nooxy Configuration
278+
279+
```javascript
280+
nooxy: {
281+
// Show "Made with Nooxy" badge in header
282+
// Default: true - set to false to hide the badge
283+
showBadge: true,
284+
}
285+
```
286+
277287
### Optional Features
278288

279289
| Field | Description |

examples/cloudflare/nooxy/config.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,16 @@ export const SITE_CONFIG = {
145145
// // aiAttribution: 'Your Name - example.com',
146146
// },
147147

148+
// ============================================================================
149+
// OPTIONAL: Nooxy Configuration
150+
// ============================================================================
151+
152+
// nooxy: {
153+
// // Show "Made with Nooxy" badge in header
154+
// // Default: true - set to false to hide the badge
155+
// showBadge: true,
156+
// },
157+
148158
// ============================================================================
149159
// ADVANCED: Custom Code Injection
150160
// ============================================================================

examples/cloudflare/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,6 @@
1616
"wrangler": "^4.32.0"
1717
},
1818
"dependencies": {
19-
"nooxy": "^1.7.1"
19+
"nooxy": "^1.8.0"
2020
}
2121
}

src/cli/templates/config.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,16 @@ export const SITE_CONFIG = {
145145
// // aiAttribution: 'Your Name - example.com',
146146
// },
147147

148+
// ============================================================================
149+
// OPTIONAL: Nooxy Configuration
150+
// ============================================================================
151+
152+
// nooxy: {
153+
// // Show "Made with Nooxy" badge in header
154+
// // Default: true - set to false to hide the badge
155+
// showBadge: true,
156+
// },
157+
148158
// ============================================================================
149159
// ADVANCED: Custom Code Injection
150160
// ============================================================================
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
export const HEAD_JS_STRING = `function buildCustomHeader(customHeader){return \`<div class="nooxyBadge_4f7c2b1a-demo-topbar">\${customHeader ?? ''}<a class="nooxyBadge_4f7c2b1a-badge-link" style="cursor: pointer;" href="https://github.com/draphy/nooxy" tabindex="0" target="_blank" rel="noopener noreferrer"><!--Subtle shine effect--><span class="nooxyBadge_4f7c2b1a-badge-shine"></span><!--Sparkle icon--><svg class="nooxyBadge_4f7c2b1a-badge-icon" width="10" height="10" viewBox="0 0 24 24" fill="currentColor"><path d="M12 0l3.09 6.26L22 9.27l-6.91 3.01L12 24l-3.09-11.72L2 9.27l6.91-3.01L12 0z"/></svg>Made with Nooxy</a></div>\`;}const cusHeaderInterval=setInterval(()=>{const header=document.querySelector('header');const injectedHeader=document.querySelector('.nooxyBadge_4f7c2b1a-demo-topbar');if(header&&!injectedHeader){header.insertAdjacentHTML('afterbegin',buildCustomHeader(customHeader));clearInterval(cusHeaderInterval);}},300);function extractSlug(url){if(url.startsWith('/')){return url.split('?')[0];}try{const u=new URL(url);return u.pathname;}catch(_e){return url.split('?')[0];}}function extractPageId(input){const path=input.split('?')[0];const match=path.match(/([a-fA-F0-9]{32})(?=\\/?$)/);return match ? match[1]:'';}window.nooxy={_slugToPage:slugToPage,_pageToSlug:pageToSlug,_notionDomain:notionDomain,_myUrl:function(url){const notionUrl=url.replace(location.origin,this._notionDomain);const slug=extractSlug(notionUrl);const pageId=slugToPage[slug];if(pageId){const regex=new RegExp(\`\${slug}(?=\\\\?|$)\`);return notionUrl.replace(regex,\`/\${pageId}\`);}return notionUrl;},_yourUrl:function(url){const cDomainUrl=url.replace(this._notionDomain,location.origin);const pageId=extractPageId(cDomainUrl);const slug=pageToSlug[pageId];if(slug){return cDomainUrl.replace(new RegExp(\`(^|[^/])\\\\/[^/].*\${pageId}(?=\\\\?|$)\`),\`$1\${slug}\`);}return cDomainUrl;},href:function(){return this._myUrl(location.href);},};window.history.pushState=new Proxy(window.history.pushState,{apply:function(target,that,args){const data=args[0];const unused=args[1];const url=args[2];return Reflect.apply(target,that,[data,unused,window.nooxy._yourUrl(url)]);},});window.history.replaceState=new Proxy(window.history.replaceState,{apply:function(target,that,args){const data=args[0];const unused=args[1];const url=args[2];return Reflect.apply(target,that,[data,unused,window.nooxy._yourUrl(url)]);},});(function(){const replacedUrl=function(url){const match=/^https?:\\/\\/([^\\\\/]*)/.exec(url);const domain=match ? match[1]:'';if((domain.endsWith('notion.so')&&!domain.endsWith('msgstore.www.notion.so'))||domain.endsWith('splunkcloud.com')||domain.endsWith('statsigapi.net')){return url.replace(/^.*:(.*)\\/\\//,'/200/$1');}return url;};window.fetch=new Proxy(window.fetch,{apply:function(target,that,args){let url=args[0];const rest=Array.prototype.slice.call(args,1);url=replacedUrl(url);return Reflect.apply(target,that,[url].concat(rest));},});window.XMLHttpRequest=new Proxy(XMLHttpRequest,{construct:function(target,args){const xhr=new(Function.prototype.bind.apply(target,[null].concat(args)))();xhr.open=new Proxy(xhr.open,{apply:function(target,that,args){const method=args[0];let url=args[1];const rest=Array.prototype.slice.call(args,2);url=replacedUrl(url);return Reflect.apply(target,that,[method,url].concat(rest));},});return xhr;},});})();`;
1+
export const HEAD_JS_STRING = `function buildCustomHeader(customHeader,showBadge){const badge=showBadge ? \`<a class="nooxyBadge_4f7c2b1a-badge-link" style="cursor: pointer;" href="https://github.com/draphy/nooxy" tabindex="0" target="_blank" rel="noopener noreferrer"><!--Subtle shine effect--><span class="nooxyBadge_4f7c2b1a-badge-shine"></span><!--Sparkle icon--><svg class="nooxyBadge_4f7c2b1a-badge-icon" width="10" height="10" viewBox="0 0 24 24" fill="currentColor"><path d="M12 0l3.09 6.26L22 9.27l-6.91 3.01L12 24l-3.09-11.72L2 9.27l6.91-3.01L12 0z"/></svg>Made with Nooxy</a>\`:'';return \`<div class="nooxyBadge_4f7c2b1a-demo-topbar">\${customHeader ?? ''}\${badge}</div>\`;}const cusHeaderInterval=setInterval(()=>{const header=document.querySelector('header');const injectedHeader=document.querySelector('.nooxyBadge_4f7c2b1a-demo-topbar');if(header&&!injectedHeader){header.insertAdjacentHTML('afterbegin',buildCustomHeader(customHeader,showBadge));clearInterval(cusHeaderInterval);}},300);function extractSlug(url){if(url.startsWith('/')){return url.split('?')[0];}try{const u=new URL(url);return u.pathname;}catch(_e){return url.split('?')[0];}}function extractPageId(input){const path=input.split('?')[0];const match=path.match(/([a-fA-F0-9]{32})(?=\\/?$)/);return match ? match[1]:'';}window.nooxy={_slugToPage:slugToPage,_pageToSlug:pageToSlug,_notionDomain:notionDomain,_myUrl:function(url){const notionUrl=url.replace(location.origin,this._notionDomain);const slug=extractSlug(notionUrl);const pageId=slugToPage[slug];if(pageId){const regex=new RegExp(\`\${slug}(?=\\\\?|$)\`);return notionUrl.replace(regex,\`/\${pageId}\`);}return notionUrl;},_yourUrl:function(url){const cDomainUrl=url.replace(this._notionDomain,location.origin);const pageId=extractPageId(cDomainUrl);const slug=pageToSlug[pageId];if(slug){return cDomainUrl.replace(new RegExp(\`(^|[^/])\\\\/[^/].*\${pageId}(?=\\\\?|$)\`),\`$1\${slug}\`);}return cDomainUrl;},href:function(){return this._myUrl(location.href);},};window.history.pushState=new Proxy(window.history.pushState,{apply:function(target,that,args){const data=args[0];const unused=args[1];const url=args[2];return Reflect.apply(target,that,[data,unused,window.nooxy._yourUrl(url)]);},});window.history.replaceState=new Proxy(window.history.replaceState,{apply:function(target,that,args){const data=args[0];const unused=args[1];const url=args[2];return Reflect.apply(target,that,[data,unused,window.nooxy._yourUrl(url)]);},});(function(){const replacedUrl=function(url){const match=/^https?:\\/\\/([^\\\\/]*)/.exec(url);const domain=match ? match[1]:'';if((domain.endsWith('notion.so')&&!domain.endsWith('msgstore.www.notion.so'))||domain.endsWith('splunkcloud.com')||domain.endsWith('statsigapi.net')){return url.replace(/^.*:(.*)\\/\\//,'/200/$1');}return url;};window.fetch=new Proxy(window.fetch,{apply:function(target,that,args){let url=args[0];const rest=Array.prototype.slice.call(args,1);url=replacedUrl(url);return Reflect.apply(target,that,[url].concat(rest));},});window.XMLHttpRequest=new Proxy(XMLHttpRequest,{construct:function(target,args){const xhr=new(Function.prototype.bind.apply(target,[null].concat(args)))();xhr.open=new Proxy(xhr.open,{apply:function(target,that,args){const method=args[0];let url=args[1];const rest=Array.prototype.slice.call(args,2);url=replacedUrl(url);return Reflect.apply(target,that,[method,url].concat(rest));},});return xhr;},});})();`;

src/rewriters/custom/head.js

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
1-
function buildCustomHeader(customHeader) {
2-
return `
3-
<div class="nooxyBadge_4f7c2b1a-demo-topbar">
4-
${customHeader ?? ''}
5-
<a class="nooxyBadge_4f7c2b1a-badge-link" style="cursor: pointer;" href="https://github.com/draphy/nooxy" tabindex="0" target="_blank" rel="noopener noreferrer">
1+
function buildCustomHeader(customHeader, showBadge) {
2+
const badge = showBadge
3+
? `<a class="nooxyBadge_4f7c2b1a-badge-link" style="cursor: pointer;" href="https://github.com/draphy/nooxy" tabindex="0" target="_blank" rel="noopener noreferrer">
64
<!-- Subtle shine effect -->
75
<span class="nooxyBadge_4f7c2b1a-badge-shine"></span>
86
<!-- Sparkle icon -->
@@ -18,7 +16,12 @@ function buildCustomHeader(customHeader) {
1816
/>
1917
</svg>
2018
Made with Nooxy
21-
</a>
19+
</a>`
20+
: '';
21+
return `
22+
<div class="nooxyBadge_4f7c2b1a-demo-topbar">
23+
${customHeader ?? ''}
24+
${badge}
2225
</div>
2326
`;
2427
}
@@ -28,7 +31,7 @@ const cusHeaderInterval = setInterval(() => {
2831
const injectedHeader = document.querySelector('.nooxyBadge_4f7c2b1a-demo-topbar');
2932

3033
if (header && !injectedHeader) {
31-
header.insertAdjacentHTML('afterbegin', buildCustomHeader(customHeader));
34+
header.insertAdjacentHTML('afterbegin', buildCustomHeader(customHeader, showBadge));
3235
clearInterval(cusHeaderInterval);
3336
}
3437
}, 300);

src/rewriters/data-rewriter.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,15 @@ export function modifyResponseData(
3535
customBodyJS,
3636
googleFont,
3737
seo,
38+
nooxy,
3839
} = siteConfig;
3940
let data = responseData;
4041
const notionDomainUrl = new URL(ensureHttpsUrl(notionDomain)).origin;
4142

4243
const targetDomain = seo?.canonicalDomain || domain;
4344
const safeCustomHeader = escapeForJS(customHeader || '');
44-
const customJSCode = `var notionDomain='${notionDomainUrl}',slugToPage=${JSON.stringify(slugToPage)},pageToSlug=${JSON.stringify(pageToSlug)},customHeader='${safeCustomHeader}';${HEAD_JS_STRING}`;
45+
const showBadge = nooxy?.showBadge !== false; // Default: true
46+
const customJSCode = `var notionDomain='${notionDomainUrl}',slugToPage=${JSON.stringify(slugToPage)},pageToSlug=${JSON.stringify(pageToSlug)},customHeader='${safeCustomHeader}',showBadge=${showBadge};${HEAD_JS_STRING}`;
4547
const googleFontInject = googleFont
4648
? `<link href='https://fonts.googleapis.com/css?family=${googleFont.replace(
4749
/ /g,

src/types.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,21 @@ export interface NooxySiteConfigFull {
4141
// SEO configuration
4242
seo?: NooxySeoConfig
4343

44+
// Nooxy-specific configuration
45+
nooxy?: NooxyConfig
46+
4447
// Calculated fields
4548
pageToSlug: Record<string, string>
4649
slugs: Array<string>
4750
}
4851

52+
// Nooxy-specific configuration
53+
export interface NooxyConfig {
54+
// Show "Made with Nooxy" badge in header
55+
// Default: true
56+
showBadge?: boolean
57+
}
58+
4959
// SEO configuration
5060
export interface NooxySeoConfig {
5161
// Enable search engine indexing (removes noindex, adds canonical URL, adds robots meta)

0 commit comments

Comments
 (0)