Skip to content

Commit 65eecb9

Browse files
authored
Merge pull request #26 from classmethod/feature/seo-enhancements
Add branding options and Twitter handle support
2 parents 3035e47 + ca8fb6d commit 65eecb9

2 files changed

Lines changed: 101 additions & 2 deletions

File tree

src/App.tsx

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ import code, {
4141
ImageOptions,
4242
PageMetadata,
4343
StructuredDataOptions,
44+
BrandingOptions,
4445
} from "./code";
4546
import "./styles.css";
4647

@@ -141,6 +142,11 @@ export default function App() {
141142
organizationName: "",
142143
logoUrl: "",
143144
});
145+
const [branding, setBranding] = useState<BrandingOptions>({
146+
siteName: "",
147+
brandReplacement: "",
148+
twitterHandle: "",
149+
});
144150
const [slugMetadataExpanded, setSlugMetadataExpanded] = useState<
145151
Record<number, boolean>
146152
>({});
@@ -231,6 +237,17 @@ export default function App() {
231237
setCopied(false);
232238
}
233239

240+
function handleBrandingChange(
241+
field: keyof BrandingOptions,
242+
value: string,
243+
): void {
244+
setBranding({
245+
...branding,
246+
[field]: value,
247+
});
248+
setCopied(false);
249+
}
250+
234251
function toggleSlugMetadata(index: number): void {
235252
setSlugMetadataExpanded({
236253
...slugMetadataExpanded,
@@ -292,6 +309,7 @@ export default function App() {
292309
optionImage,
293310
pageMetadata,
294311
structuredData,
312+
branding,
295313
};
296314

297315
const script = noError ? code(codeData) : undefined;
@@ -711,6 +729,55 @@ export default function App() {
711729
size="small"
712730
/>
713731

732+
<Box sx={{ mt: 3, pt: 2, borderTop: 1, borderColor: "grey.300" }}>
733+
<Typography
734+
variant="subtitle2"
735+
color="text.secondary"
736+
gutterBottom
737+
>
738+
Branding & Social
739+
</Typography>
740+
<TextField
741+
fullWidth
742+
label="Site Name"
743+
margin="dense"
744+
placeholder="My Awesome Site"
745+
helperText="Used for og:site_name meta tag"
746+
onChange={(e) =>
747+
handleBrandingChange("siteName", e.target.value)
748+
}
749+
value={branding.siteName}
750+
variant="outlined"
751+
size="small"
752+
/>
753+
<TextField
754+
fullWidth
755+
label="Brand Replacement"
756+
margin="dense"
757+
placeholder="My Brand"
758+
helperText="Replaces 'Notion' text in meta tags (optional)"
759+
onChange={(e) =>
760+
handleBrandingChange("brandReplacement", e.target.value)
761+
}
762+
value={branding.brandReplacement}
763+
variant="outlined"
764+
size="small"
765+
/>
766+
<TextField
767+
fullWidth
768+
label="Twitter/X Handle"
769+
margin="dense"
770+
placeholder="@username"
771+
helperText="For twitter:site and twitter:creator meta tags"
772+
onChange={(e) =>
773+
handleBrandingChange("twitterHandle", e.target.value)
774+
}
775+
value={branding.twitterHandle}
776+
variant="outlined"
777+
size="small"
778+
/>
779+
</Box>
780+
714781
<Box sx={{ mt: 3, pt: 2, borderTop: 1, borderColor: "grey.300" }}>
715782
<Stack
716783
direction="row"

src/code.ts

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,12 @@ export interface StructuredDataOptions {
2323
logoUrl?: string;
2424
}
2525

26+
export interface BrandingOptions {
27+
siteName?: string;
28+
brandReplacement?: string;
29+
twitterHandle?: string;
30+
}
31+
2632
export interface CodeData {
2733
myDomain: string;
2834
notionUrl: string;
@@ -35,6 +41,7 @@ export interface CodeData {
3541
optionImage: ImageOptions;
3642
pageMetadata: Record<string, PageMetadata>;
3743
structuredData: StructuredDataOptions;
44+
branding: BrandingOptions;
3845
}
3946

4047
function getId(url: string): string {
@@ -60,6 +67,7 @@ export default function code(data: CodeData): string {
6067
optionImage,
6168
pageMetadata,
6269
structuredData,
70+
branding,
6371
} = data;
6472
let url = myDomain.replace("https://", "").replace("http://", "");
6573
if (url.slice(-1) === "/") url = url.slice(0, url.length - 1);
@@ -103,6 +111,14 @@ ${slugs
103111
const ORGANIZATION_NAME = '${structuredData?.organizationName || ""}';
104112
const LOGO_URL = '${structuredData?.logoUrl || ""}';
105113
114+
/*
115+
* Step 3.3: branding configuration (optional)
116+
* Replace Notion branding with your own and add social media handles
117+
*/
118+
const SITE_NAME = '${branding?.siteName || ""}';
119+
const BRAND_REPLACEMENT = '${branding?.brandReplacement || ""}';
120+
const TWITTER_HANDLE = '${branding?.twitterHandle || ""}';
121+
106122
/* Step 4: enter a Google Font name, you can choose from https://fonts.google.com */
107123
const GOOGLE_FONT = '${googleFont || ""}';
108124
@@ -355,11 +371,21 @@ ${slugs
355371
return;
356372
}
357373
}
358-
if (MY_DOMAIN !== '') {
359-
if (element.getAttribute('property') === 'og:site_name') {
374+
// Set og:site_name - use SITE_NAME if configured, otherwise MY_DOMAIN (Issue #18)
375+
if (element.getAttribute('property') === 'og:site_name') {
376+
if (SITE_NAME !== '') {
377+
element.setAttribute('content', SITE_NAME);
378+
} else if (MY_DOMAIN !== '') {
360379
element.setAttribute('content', MY_DOMAIN);
361380
}
362381
}
382+
// Replace 'Notion' branding in meta content (Issue #18)
383+
if (BRAND_REPLACEMENT !== '') {
384+
const content = element.getAttribute('content');
385+
if (content && content.includes('Notion')) {
386+
element.setAttribute('content', content.replace(/Notion/g, BRAND_REPLACEMENT));
387+
}
388+
}
363389
if (pageTitle !== '') {
364390
if (element.getAttribute('property') === 'og:title'
365391
|| element.getAttribute('name') === 'twitter:title') {
@@ -405,6 +431,12 @@ ${slugs
405431
element.append(\`<link rel="canonical" href="\${canonicalUrl}">\`, { html: true });
406432
element.append(\`<meta name="robots" content="index, follow">\`, { html: true });
407433
434+
// Add Twitter/X meta tags for social cards (Issue #19)
435+
if (TWITTER_HANDLE !== '') {
436+
element.append(\`<meta name="twitter:site" content="\${TWITTER_HANDLE}">\`, { html: true });
437+
element.append(\`<meta name="twitter:creator" content="\${TWITTER_HANDLE}">\`, { html: true });
438+
}
439+
408440
// Add JSON-LD structured data for rich search results (Issue #10)
409441
if (STRUCTURED_DATA_ENABLED) {
410442
const pageTitle = this.metadata.title || PAGE_TITLE;

0 commit comments

Comments
 (0)