@clidey/dory 0.27.0 → 0.29.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.html CHANGED
@@ -7,14 +7,14 @@
7
7
  <meta name="theme-color" content="#000000" />
8
8
 
9
9
  <!-- Primary Meta Tags -->
10
- <meta name="description" content="Docucod generates and maintains up-to-date documentation from your codebase so your team can move fast, onboard quickly, and stay focused on building." />
10
+ <meta name="description" content="Docucod - Technical Documentation" />
11
11
  <meta name="keywords" content="documentation, code documentation, auto documentation, developer tools, technical documentation, codebase documentation, llm, ai, anthropic, openai, chatgpt, claude, clidey" />
12
12
  <meta name="author" content="Clidey" />
13
13
  <meta name="language" content="English" />
14
14
 
15
15
  <!-- Open Graph / Facebook -->
16
- <meta property="og:title" content="Docucod: Generate and Maintain Documentation With No Work" />
17
- <meta property="og:description" content="Docucod auto-generates and maintains up-to-date documentation from your codebase so your team can move fast, onboard quickly, and stay focused on building." />
16
+ <meta property="og:title" content="Docucod" />
17
+ <meta property="og:description" content="Docucod - Technical Documentation" />
18
18
  <meta property="og:image" content="/assets/favicon-nLquwUQp.svg" />
19
19
  <meta property="og:url" content="https://docucod.com/" />
20
20
  <meta property="og:type" content="website" />
@@ -23,8 +23,8 @@
23
23
 
24
24
  <!-- Twitter -->
25
25
  <meta name="twitter:card" content="summary_large_image" />
26
- <meta name="twitter:title" content="Docucod: Generate and Maintain Documentation With No Work" />
27
- <meta name="twitter:description" content="Docucod auto-generates and maintains up-to-date documentation from your codebase so your team can move fast, onboard quickly, and stay focused on building." />
26
+ <meta name="twitter:title" content="Docucod" />
27
+ <meta name="twitter:description" content="Docucod - Technical Documentation" />
28
28
  <meta name="twitter:image" content="/assets/favicon-nLquwUQp.svg" />
29
29
  <meta name="twitter:site" content="@ClideyOfficial" />
30
30
  <meta name="twitter:creator" content="@ClideyOfficial" />
@@ -32,7 +32,7 @@
32
32
  <link rel="apple-touch-icon" href="/assets/favicon-nLquwUQp.svg" />
33
33
  <link rel="manifest" href="/manifest.json" />
34
34
 
35
- <title>Docucod - Instantly Generate and Maintain Your Documentation</title>
35
+ <title>Docucod</title>
36
36
 
37
37
  <link rel="preconnect" href="https://fonts.googleapis.com" />
38
38
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
@@ -45,7 +45,7 @@
45
45
  person_profiles: 'identified_only', // or 'always' to create profiles for anonymous users as well
46
46
  })
47
47
  </script>
48
- <script type="module" crossorigin src="/assets/index-CPVd_vt1.js"></script>
48
+ <script type="module" crossorigin src="/assets/index-B2MKmN57.js"></script>
49
49
  <link rel="stylesheet" crossorigin href="/assets/index-Btb13Da-.css">
50
50
  </head>
51
51
  <body>
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@clidey/dory",
3
3
  "private": false,
4
- "version": "0.27.0",
4
+ "version": "0.29.0",
5
5
  "type": "module",
6
6
  "description": "A CLI tool for building and previewing documentation sites",
7
7
  "keywords": [
@@ -0,0 +1,76 @@
1
+ import type { Plugin } from 'vite';
2
+ import { readFileSync, existsSync } from 'fs';
3
+ import { resolve } from 'path';
4
+
5
+ /**
6
+ * Vite plugin that injects site metadata from dory.json into index.html
7
+ * This provides proper defaults before JavaScript hydrates the page
8
+ */
9
+ export function htmlMetadataInjector(): Plugin {
10
+ return {
11
+ name: 'html-metadata-injector',
12
+ transformIndexHtml(html) {
13
+ // Read dory.json configuration
14
+ const doryJsonPath = resolve(process.cwd(), 'docs', 'dory.json');
15
+
16
+ if (!existsSync(doryJsonPath)) {
17
+ console.warn('⚠️ dory.json not found, using default metadata');
18
+ return html;
19
+ }
20
+
21
+ try {
22
+ const config = JSON.parse(readFileSync(doryJsonPath, 'utf-8'));
23
+ const siteName = config.name || 'Documentation';
24
+ const defaultTitle = config.title || siteName;
25
+ const defaultDescription = config.description || `${siteName} - Technical Documentation`;
26
+
27
+ // Replace title
28
+ html = html.replace(
29
+ /<title>.*?<\/title>/,
30
+ `<title>${defaultTitle}</title>`
31
+ );
32
+
33
+ // Replace meta description
34
+ html = html.replace(
35
+ /<meta name="description" content=".*?" \/>/,
36
+ `<meta name="description" content="${defaultDescription}" />`
37
+ );
38
+
39
+ // Replace Open Graph title
40
+ html = html.replace(
41
+ /<meta property="og:title" content=".*?" \/>/,
42
+ `<meta property="og:title" content="${defaultTitle}" />`
43
+ );
44
+
45
+ // Replace Open Graph description
46
+ html = html.replace(
47
+ /<meta property="og:description" content=".*?" \/>/,
48
+ `<meta property="og:description" content="${defaultDescription}" />`
49
+ );
50
+
51
+ // Replace Open Graph site name
52
+ html = html.replace(
53
+ /<meta property="og:site_name" content=".*?" \/>/,
54
+ `<meta property="og:site_name" content="${siteName}" />`
55
+ );
56
+
57
+ // Replace Twitter title
58
+ html = html.replace(
59
+ /<meta name="twitter:title" content=".*?" \/>/,
60
+ `<meta name="twitter:title" content="${defaultTitle}" />`
61
+ );
62
+
63
+ // Replace Twitter description
64
+ html = html.replace(
65
+ /<meta name="twitter:description" content=".*?" \/>/,
66
+ `<meta name="twitter:description" content="${defaultDescription}" />`
67
+ );
68
+
69
+ return html;
70
+ } catch (error) {
71
+ console.error('❌ Failed to parse dory.json for metadata injection:', error);
72
+ return html;
73
+ }
74
+ },
75
+ };
76
+ }
package/src/ui/layout.tsx CHANGED
@@ -83,28 +83,61 @@ export default function Layout({ children }: LayoutProps) {
83
83
  });
84
84
  }, [pathname]);
85
85
 
86
- const { title: group, group: title } = useMemo(() => {
87
- const group = ALL_NAVIGATION.flatMap((tab) =>
88
- tab.groups.find((group) =>
86
+ const { title: group, group: title, page } = useMemo(() => {
87
+ const group = ALL_NAVIGATION.flatMap((tab) =>
88
+ tab.groups.find((group) =>
89
89
  group.pages.some((page) => page.href === pathname)
90
90
  )
91
91
  );
92
92
  const page = completeFrontMatter.find((page) => page.path === pathname);
93
93
 
94
- useEffect(() => {
95
- if (page?.title) {
96
- document.title = page.title;
94
+ return { group: group[0]?.title, title: page?.title, page };
95
+ }, [pathname, loading]);
96
+
97
+ // Update document title and meta tags when page changes
98
+ useEffect(() => {
99
+ if (page?.title) {
100
+ document.title = page.title;
101
+
102
+ // Update Open Graph title
103
+ const ogTitle = document.querySelector('meta[property="og:title"]');
104
+ if (ogTitle) {
105
+ ogTitle.setAttribute('content', page.title);
97
106
  }
98
- if (page?.description) {
99
- const metaDescription = document.querySelector('meta[name="description"]');
100
- if (metaDescription) {
101
- metaDescription.setAttribute('content', page.description);
102
- }
107
+
108
+ // Update Twitter title
109
+ const twitterTitle = document.querySelector('meta[name="twitter:title"]');
110
+ if (twitterTitle) {
111
+ twitterTitle.setAttribute('content', page.title);
103
112
  }
104
- }, [page]);
113
+ }
105
114
 
106
- return { group: group[0]?.title, title: page?.title, };
107
- }, [pathname, loading]);
115
+ if (page?.description) {
116
+ // Update standard meta description
117
+ const metaDescription = document.querySelector('meta[name="description"]');
118
+ if (metaDescription) {
119
+ metaDescription.setAttribute('content', page.description);
120
+ }
121
+
122
+ // Update Open Graph description
123
+ const ogDescription = document.querySelector('meta[property="og:description"]');
124
+ if (ogDescription) {
125
+ ogDescription.setAttribute('content', page.description);
126
+ }
127
+
128
+ // Update Twitter description
129
+ const twitterDescription = document.querySelector('meta[name="twitter:description"]');
130
+ if (twitterDescription) {
131
+ twitterDescription.setAttribute('content', page.description);
132
+ }
133
+ }
134
+
135
+ // Update canonical URL
136
+ const ogUrl = document.querySelector('meta[property="og:url"]');
137
+ if (ogUrl) {
138
+ ogUrl.setAttribute('content', window.location.href);
139
+ }
140
+ }, [page]);
108
141
 
109
142
  const tab = useMemo(() => {
110
143
  return completeFrontMatter.find((page) => page.path === pathname);
package/vite.config.ts CHANGED
@@ -8,6 +8,7 @@ import { llmTxtDevServer } from './src/plugins/llm-txt-dev-server';
8
8
  import { frontmatterGenerator } from './src/plugins/frontmatter-generator';
9
9
  import { frontmatterDevServer } from './src/plugins/frontmatter-dev-server';
10
10
  import { docsAssetsPlugin } from './src/plugins/docs-assets';
11
+ import { htmlMetadataInjector } from './src/plugins/html-metadata-injector';
11
12
  import { getMdxConfig } from './src/config/mdx';
12
13
 
13
14
  export default defineConfig(({ command }) => ({
@@ -22,6 +23,7 @@ export default defineConfig(({ command }) => ({
22
23
  frontmatterGenerator(),
23
24
  frontmatterDevServer(),
24
25
  docsAssetsPlugin(),
26
+ htmlMetadataInjector(),
25
27
  ],
26
28
  resolve: {
27
29
  alias: {