The blog-analytics.tsx client component was importing from the @/lib/blog
barrel export, which transitively included content.ts that uses the Node.js
fs module. This caused the build to fail with "Module not found: Cannot
resolve fs" error.
Changed imports to use direct file paths:
- Import BlogPost type from @/lib/blog/types
- Import analytics functions from @/lib/blog/analytics
This avoids pulling content.ts into the client bundle.
- Create sitemap.ts with MetadataRoute.Sitemap for Next.js
- Include all static pages with priorities and change frequencies
- Include /blog index page (priority 0.8, daily updates)
- Dynamically include all published blog post URLs (/blog/[slug])
- Blog posts use publish_date as lastModified
The sitemap is referenced by robots.ts at /sitemap.xml
MKT-71
- Add SUBSTACK link to constants.ts
- Add Blog link to desktop nav Resources dropdown
- Add Blog link to mobile nav Resources section
- Add Blog link to footer Resources section
- Add Substack link to footer Connect section
MKT-72
- Add analytics.ts with blog-specific tracking events:
- trackBlogIndexView: Track blog index views with post count
- trackBlogPostView: Track individual post views with metadata
- trackBlogPostScrollDepth: Track reading progress (25%, 50%, 75%, 100%)
- trackBlogPostTimeSpent: Track time spent on posts
- trackBlogPostShare: Track social share clicks
- trackBlogPostCTAClick: Track CTA engagement
- Add BlogIndexAnalytics and BlogPostAnalytics client components
- Integrate analytics into /blog and /blog/[slug] pages
Attribution is handled by PostHog save_referrer and save_campaign_params.
MKT-74
- Add structured-data.ts with Article, CollectionPage, and BreadcrumbList schemas
- Integrate JSON-LD into /blog index page (Blog collection + breadcrumbs)
- Integrate JSON-LD into /blog/[slug] page (Article + post breadcrumbs)
- Export structured data utilities from blog module index
MKT-70
- Create dynamic route for individual blog posts
- Use force-dynamic for request-time publish gating
- Require Node.js runtime for filesystem reads
- Return 404 for drafts, future posts, or invalid slugs
- Render Markdown with react-markdown + remark-gfm
- No raw HTML rendering (safe by default)
- Include consistent typography and styling
Closes: MKT-69
- Create blog index page at /blog
- Use force-dynamic for request-time publish gating
- Require Node.js runtime for filesystem reads
- Display posts with title, description, and date
- Add empty state when no posts are published
- Include tags display (up to 3)
Closes: MKT-68
copy: update /slack page messaging
- Update trial CTA to 'Start a free 14 day Team trial'
- Replace 'humans' with 'your team' in value props subtitle
- Shorten value prop titles for consistent one-line display
- Improve Thread-aware and Open to all descriptions
* Removes Pro, restructures pricing page
* Solves provider/credits
* Update apps/web-roo-code/src/app/pricing/page.tsx
Co-authored-by: roomote[bot] <219738659+roomote[bot]@users.noreply.github.com>
* Updates agent landing pages to not mention a trial that doesn't exist
* Updates agent-specific landing pages to reflect new home and trial
* Indicate the agent landing page the user came from
* Clean up the carousel
---------
Co-authored-by: roomote[bot] <219738659+roomote[bot]@users.noreply.github.com>
- Updated variant A content to match variant B messaging
- Both variants now show the same improved copy focused on catching meaningful bugs
- Emphasizes depth over token-saving and repository-aware analysis
Co-authored-by: Roo Code <roomote@roocode.com>
* feat: add Google Tag Manager to marketing website using Next.js Script component
* refactor: remove Google Ads implementation in favor of Tag Manager
* fix: wrap GTM script in consent-checking client component for GDPR compliance
---------
Co-authored-by: Roo Code <roomote@roocode.com>
* feat: implement Google Consent Mode v2 with cookieless pings
- Add consent defaults before gtag.js loads (required for Consent Mode v2)
- Enable cookieless pings with url_passthrough for Google Ads
- Implement consent update logic for all consent categories
- Support both granted and denied consent states
- Maintain backward compatibility with existing consent manager
* fix: remove shouldLoad from useEffect dependency array to prevent re-initialization loop
---------
Co-authored-by: Roo Code <roomote@roocode.com>