@m13v/seo-components 0.8.1 → 0.8.2
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/LICENSE +21 -0
- package/README.md +146 -0
- package/package.json +2 -3
- package/src/components/GuideChatPanel.tsx +12 -12
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 m13v
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
# @m13v/seo-components
|
|
2
|
+
|
|
3
|
+
42 animated React components for programmatic SEO pages. Ships as TypeScript source (no build step); Next.js transpiles it directly.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @seo/components@npm:@m13v/seo-components
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
This aliases the package so you import from `@seo/components` everywhere.
|
|
12
|
+
|
|
13
|
+
## Usage
|
|
14
|
+
|
|
15
|
+
```tsx
|
|
16
|
+
// Client components
|
|
17
|
+
import { Breadcrumbs, ArticleMeta, FaqSection, ComparisonTable } from "@seo/components";
|
|
18
|
+
import { SitemapSidebar, GuideChatPanel, HeadingAnchors } from "@seo/components";
|
|
19
|
+
import { AnimatedBeam, MorphingText, NumberTicker, Particles } from "@seo/components";
|
|
20
|
+
|
|
21
|
+
// Server utilities (API routes, server components)
|
|
22
|
+
import { walkPages, createGuideChatHandler, discoverGuides } from "@seo/components/server";
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Components
|
|
26
|
+
|
|
27
|
+
### Trust & Content
|
|
28
|
+
|
|
29
|
+
| Component | What it does |
|
|
30
|
+
|-----------|-------------|
|
|
31
|
+
| `Breadcrumbs` | SEO breadcrumb trail with JSON-LD |
|
|
32
|
+
| `ArticleMeta` | Author, date, read time |
|
|
33
|
+
| `FaqSection` | Expandable FAQ with `FAQPage` schema |
|
|
34
|
+
| `ComparisonTable` | Feature comparison grid |
|
|
35
|
+
| `ProofBand` | Logo/stat proof strip |
|
|
36
|
+
| `ProofBanner` | Quote + metric banner |
|
|
37
|
+
| `InlineTestimonial` | Inline quote block |
|
|
38
|
+
|
|
39
|
+
### Animation (Magic UI style)
|
|
40
|
+
|
|
41
|
+
| Component | What it does |
|
|
42
|
+
|-----------|-------------|
|
|
43
|
+
| `AnimatedBeam` | SVG beam connecting elements |
|
|
44
|
+
| `MorphingText` | Text that morphs between strings |
|
|
45
|
+
| `NumberTicker` | Counting number animation |
|
|
46
|
+
| `OrbitingCircles` | Orbiting icon circles |
|
|
47
|
+
| `Particles` | Interactive particle field |
|
|
48
|
+
| `Marquee` | Infinite scroll marquee |
|
|
49
|
+
| `ShimmerButton` | Button with shimmer effect |
|
|
50
|
+
| `GradientText` | Animated gradient text |
|
|
51
|
+
| `TextShimmer` | Shimmering text highlight |
|
|
52
|
+
| `TypingAnimation` | Typewriter effect |
|
|
53
|
+
| `ShineBorder` | Animated border glow |
|
|
54
|
+
| `BackgroundGrid` | Dot/line grid background |
|
|
55
|
+
|
|
56
|
+
### Layout & Display
|
|
57
|
+
|
|
58
|
+
| Component | What it does |
|
|
59
|
+
|-----------|-------------|
|
|
60
|
+
| `BentoGrid` | Responsive bento card grid |
|
|
61
|
+
| `BeforeAfter` | Side-by-side before/after |
|
|
62
|
+
| `AnimatedDemo` | Animated product demo frame |
|
|
63
|
+
| `GlowCard` | Card with glow on hover |
|
|
64
|
+
| `ParallaxSection` | Parallax scroll section |
|
|
65
|
+
| `StepTimeline` | Numbered step timeline |
|
|
66
|
+
| `MotionSequence` | Sequenced entrance animations |
|
|
67
|
+
| `AnimatedSection` | Fade-in section wrapper |
|
|
68
|
+
| `AnimatedMetric` | Single animated stat |
|
|
69
|
+
| `MetricsRow` | Row of animated stats |
|
|
70
|
+
|
|
71
|
+
### Code & Technical
|
|
72
|
+
|
|
73
|
+
| Component | What it does |
|
|
74
|
+
|-----------|-------------|
|
|
75
|
+
| `AnimatedCodeBlock` | Syntax-highlighted code with line animations |
|
|
76
|
+
| `CodeComparison` | Side-by-side code diff |
|
|
77
|
+
| `TerminalOutput` | Terminal-style output |
|
|
78
|
+
| `FlowDiagram` | Animated flow chart |
|
|
79
|
+
| `SequenceDiagram` | Step sequence diagram |
|
|
80
|
+
| `AnimatedChecklist` | Animated checkbox list |
|
|
81
|
+
|
|
82
|
+
### CTA
|
|
83
|
+
|
|
84
|
+
| Component | What it does |
|
|
85
|
+
|-----------|-------------|
|
|
86
|
+
| `InlineCta` | Inline call-to-action block |
|
|
87
|
+
| `StickyBottomCta` | Fixed bottom CTA bar |
|
|
88
|
+
|
|
89
|
+
### Interactive
|
|
90
|
+
|
|
91
|
+
| Component | What it does |
|
|
92
|
+
|-----------|-------------|
|
|
93
|
+
| `SitemapSidebar` | Universal sidebar with search, page discovery, subsection tracking |
|
|
94
|
+
| `HeadingAnchors` | Auto-injects `id` on H2s for sidebar linking |
|
|
95
|
+
| `GuideChatPanel` | AI page assistant with Gemini streaming (NDJSON) |
|
|
96
|
+
|
|
97
|
+
### Video
|
|
98
|
+
|
|
99
|
+
| Component | What it does |
|
|
100
|
+
|-----------|-------------|
|
|
101
|
+
| `RemotionClip` | Remotion video player embed |
|
|
102
|
+
| `LottiePlayer` | Lottie animation player |
|
|
103
|
+
|
|
104
|
+
## Server Utilities
|
|
105
|
+
|
|
106
|
+
```tsx
|
|
107
|
+
import { walkPages, createGuideChatHandler, logAiUsage } from "@seo/components/server";
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
| Export | What it does |
|
|
111
|
+
|--------|-------------|
|
|
112
|
+
| `walkPages()` | Discovers all pages in `src/app/`, extracts titles, descriptions, H2 sections |
|
|
113
|
+
| `createGuideChatHandler()` | Gemini streaming chat route handler |
|
|
114
|
+
| `discoverGuides()` | Legacy guide discovery (delegates to `walkPages`) |
|
|
115
|
+
| `getGuideContext()` | Builds page context for AI chat |
|
|
116
|
+
| `logAiUsage()` | Token usage tracking |
|
|
117
|
+
| `getSupabaseAdmin()` | Supabase admin client |
|
|
118
|
+
| `slugify()` | URL-safe slug utility |
|
|
119
|
+
|
|
120
|
+
## JSON-LD Helpers
|
|
121
|
+
|
|
122
|
+
```tsx
|
|
123
|
+
import { breadcrumbListSchema, faqPageSchema, articleSchema, howToSchema } from "@seo/components";
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## Theming
|
|
127
|
+
|
|
128
|
+
Components use CSS variables for brand colors. Override in your `globals.css`:
|
|
129
|
+
|
|
130
|
+
```css
|
|
131
|
+
:root {
|
|
132
|
+
--seo-accent: #0d9488; /* teal-600 default */
|
|
133
|
+
--seo-accent-light: #ccfbf1; /* teal-100 */
|
|
134
|
+
--seo-accent-dark: #134e4a; /* teal-900 */
|
|
135
|
+
}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## Peer Dependencies
|
|
139
|
+
|
|
140
|
+
Required: `next >= 14`, `react >= 18`, `framer-motion >= 11`
|
|
141
|
+
|
|
142
|
+
Optional: `remotion`, `@remotion/player`, `lottie-react`, `@google/generative-ai`, `posthog-js`
|
|
143
|
+
|
|
144
|
+
## License
|
|
145
|
+
|
|
146
|
+
MIT
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@m13v/seo-components",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.2",
|
|
4
4
|
"description": "39 animated React components for programmatic SEO pages. Remotion video, Magic UI style animations, trust signals, JSON-LD helpers. Teal/cyan brand, light-theme only.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./src/index.ts",
|
|
@@ -31,8 +31,7 @@
|
|
|
31
31
|
"license": "MIT",
|
|
32
32
|
"repository": {
|
|
33
33
|
"type": "git",
|
|
34
|
-
"url": "git+https://github.com/m13v/
|
|
35
|
-
"directory": "seo-components"
|
|
34
|
+
"url": "git+https://github.com/m13v/seo-components.git"
|
|
36
35
|
},
|
|
37
36
|
"publishConfig": {
|
|
38
37
|
"access": "public"
|
|
@@ -39,11 +39,10 @@ function onPosthogLoaded(fn: () => void) {
|
|
|
39
39
|
/* Slug extraction */
|
|
40
40
|
/* ------------------------------------------------------------------ */
|
|
41
41
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
return m ? m[1] : "";
|
|
42
|
+
/** Derive a slug from any pathname. "/" returns "" (hidden). */
|
|
43
|
+
function slugFromPath(pathname: string | null): string {
|
|
44
|
+
if (!pathname || pathname === "/") return "";
|
|
45
|
+
return pathname.replace(/^\/+/, "").replace(/\/+$/g, "").replace(/\//g, "-");
|
|
47
46
|
}
|
|
48
47
|
|
|
49
48
|
/* ------------------------------------------------------------------ */
|
|
@@ -305,8 +304,8 @@ export interface GuideChatPanelProps {
|
|
|
305
304
|
app?: string;
|
|
306
305
|
/** API endpoint for the guide chat. Defaults to "/api/guide-chat" */
|
|
307
306
|
apiEndpoint?: string;
|
|
308
|
-
/**
|
|
309
|
-
|
|
307
|
+
/** Paths where the chat panel should be hidden. Same prop as SitemapSidebar's hideOnPaths. */
|
|
308
|
+
hideOnPaths?: string[];
|
|
310
309
|
/** Panel header label. Defaults to "page assistant" */
|
|
311
310
|
label?: string;
|
|
312
311
|
}
|
|
@@ -314,20 +313,21 @@ export interface GuideChatPanelProps {
|
|
|
314
313
|
export function GuideChatPanel({
|
|
315
314
|
app = "default",
|
|
316
315
|
apiEndpoint = "/api/guide-chat",
|
|
317
|
-
|
|
316
|
+
hideOnPaths,
|
|
318
317
|
label = "page assistant",
|
|
319
318
|
}: GuideChatPanelProps) {
|
|
320
319
|
const pathname = usePathname();
|
|
321
|
-
const slug = slugFromPath(pathname
|
|
320
|
+
const slug = slugFromPath(pathname);
|
|
321
|
+
const hidden = !slug || (hideOnPaths?.includes(pathname) ?? false);
|
|
322
322
|
|
|
323
323
|
useEffect(() => {
|
|
324
|
-
if (
|
|
324
|
+
if (hidden) return;
|
|
325
325
|
onPosthogLoaded(() =>
|
|
326
326
|
capture("guide_chat_panel_viewed", { app, slug }),
|
|
327
327
|
);
|
|
328
|
-
}, [slug, app]);
|
|
328
|
+
}, [hidden, slug, app]);
|
|
329
329
|
|
|
330
|
-
if (
|
|
330
|
+
if (hidden) return null;
|
|
331
331
|
|
|
332
332
|
return (
|
|
333
333
|
<aside className="hidden lg:flex flex-col sticky top-0 h-screen w-80 xl:w-96 bg-white border-l border-zinc-200">
|