diff --git a/.npmrc b/.npmrc
index 8477dbe..83aab43 100644
--- a/.npmrc
+++ b/.npmrc
@@ -1,2 +1,3 @@
@ciphera-net:registry=https://npm.pkg.github.com
//npm.pkg.github.com/:_authToken=${NODE_AUTH_TOKEN}
+legacy-peer-deps=true
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1a68ccb..5a0cc3e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -23,6 +23,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
### Improved
+- **Redesigned Search card on the dashboard.** The Search section of the dashboard has been completely refreshed to match the rest of Pulse. Search queries now show proportional bars so you can visually compare which queries get the most impressions. Hovering a row reveals the impression share percentage. Position badges are now color-coded — green for page 1 rankings, orange for page 2, and red for queries buried beyond page 5. You can switch between your top search queries and top pages using tabs, and expand the full list in a searchable popup without leaving the dashboard.
- **Smaller, faster tracking script.** The tracking script is now about 20% smaller. Logic like page path cleaning, referrer filtering, error page detection, and input validation has been moved from your browser to the Pulse server. This means the script loads faster on every page, and Pulse can improve these features without needing you to update anything.
- **Automatic 404 page detection.** Pulse now detects error pages (404 / "Page Not Found") automatically on the server by reading your page title — no extra setup needed. Previously this ran in the browser and couldn't be improved without updating the script. Now Pulse can recognize more error page patterns over time, including pages in other languages, without any changes on your end.
- **Smarter bot filtering.** Pulse now catches more types of automated traffic that were slipping through — like headless browsers with default screen sizes, bot farms that rotate through different locations, and bots that fire duplicate events within milliseconds. Bot detection checks have also been moved from the tracking script to the server, making the script smaller and faster for real visitors.
diff --git a/app/about/page.tsx b/app/about/page.tsx
index f37e4af..6ffa4bd 100644
--- a/app/about/page.tsx
+++ b/app/about/page.tsx
@@ -15,23 +15,23 @@ function ComparisonTable({ title, competitors }: { title: string, competitors: {
return (
Most analytics tools are overkill. They track everything, slow down your site, and require annoying cookie banners.
Pulse is different. We focus on the metrics that actually matter—visitors, pageviews, and sources—while respecting user privacy.
We love Plausible! They paved the way for privacy-friendly analytics.
Pulse offers a similar philosophy but with a focus on even deeper integration with the Ciphera ecosystem
and more flexible pricing for developers.
diff --git a/app/faq/page.tsx b/app/faq/page.tsx
index f1bcdca..8917312 100644
--- a/app/faq/page.tsx
+++ b/app/faq/page.tsx
@@ -1,37 +1,18 @@
'use client'
import { motion } from 'framer-motion'
-import { useState } from 'react'
-import { ChevronDownIcon } from '@ciphera-net/ui'
-
-const faqs = [
- {
- question: "Is Pulse GDPR compliant?",
- answer: "Yes, Pulse is GDPR compliant by design. We don't use cookies, don't collect personal data, and process all data anonymously."
- },
- {
- question: "Do I need a cookie consent banner?",
- answer: "No, you don't need a cookie consent banner. Pulse doesn't use cookies, so it's exempt from cookie consent requirements under GDPR."
- },
- {
- question: "How does Pulse track visitors?",
- answer: "We use a lightweight JavaScript snippet that sends anonymous pageview events. No cookies, no cross-session identifiers (we use sessionStorage only to group events within a single visit), and no cross-site tracking."
- },
- {
- question: "What data does Pulse collect?",
- answer: "We collect anonymous pageview data including page path, referrer, device type, browser, and country (derived from IP at request time; the IP itself is not stored). No personal information is collected."
- },
- {
- question: "How accurate is the data?",
- answer: "Our data is highly accurate. We exclude bot traffic and data center visits. Since we don't use cookies, we count unique sessions rather than unique users."
- },
- {
- question: "Can I export my data?",
- answer: "Yes, you can access all your analytics data through the dashboard. We're working on export functionality for bulk data downloads."
- }
-]
+import PulseFAQ from '@/components/marketing/PulseFAQ'
// * JSON-LD FAQ Schema for rich snippets
+const faqs = [
+ { question: "Is Pulse GDPR compliant?", answer: "Yes, Pulse is GDPR compliant by design. We don't use cookies, don't collect personal data, and process all data anonymously." },
+ { question: "Do I need a cookie consent banner?", answer: "No, you don't need a cookie consent banner. Pulse doesn't use cookies, so it's exempt from cookie consent requirements under GDPR." },
+ { question: "How does Pulse track visitors?", answer: "We use a lightweight JavaScript snippet that sends anonymous pageview events. No cookies, no cross-session identifiers (we use sessionStorage only to group events within a single visit), and no cross-site tracking." },
+ { question: "What data does Pulse collect?", answer: "We collect anonymous pageview data including page path, referrer, device type, browser, and country (derived from IP at request time; the IP itself is not stored). No personal information is collected." },
+ { question: "How accurate is the data?", answer: "Our data is highly accurate. We exclude bot traffic and data center visits. Since we don't use cookies, we count unique sessions rather than unique users." },
+ { question: "Can I export my data?", answer: "Yes, you can access all your analytics data through the dashboard. We're working on export functionality for bulk data downloads." },
+]
+
const faqSchema = {
'@context': 'https://schema.org',
'@type': 'FAQPage',
@@ -45,47 +26,6 @@ const faqSchema = {
})),
}
-function FAQItem({ faq, index }: { faq: typeof faqs[0]; index: number }) {
- const [isOpen, setIsOpen] = useState(false)
-
- return (
-
-
- {isOpen && (
-
-
Just add this snippet to your <head> tag in your layout or index file.
-
+
@@ -55,15 +53,22 @@ export default function InstallationPage() {
></script>
+
+ 1.6 KB gzipped
+
+
+ Non-blocking, async
+
+
-
Custom events (goals)
+
Custom events (goals)
- Track custom events (e.g. signup, purchase) with pulse.track('event_name'). Use letters, numbers, and underscores only. Define goals in your site Settings → Goals & Events to see counts in the dashboard.
+ Track custom events (e.g. signup, purchase) with pulse.track('event_name'). Use letters, numbers, and underscores only. Define goals in your site Settings → Goals & Events to see counts in the dashboard.
-
+
diff --git a/app/integrations/nextjs/page.tsx b/app/integrations/nextjs/page.tsx
index 2a26425..96ced7e 100644
--- a/app/integrations/nextjs/page.tsx
+++ b/app/integrations/nextjs/page.tsx
@@ -8,10 +8,9 @@ export default function NextJsIntegrationPage() {
{/* * --- ATMOSPHERE (Background) --- */}
-
-
+
@@ -26,22 +25,22 @@ export default function NextJsIntegrationPage() {
-
-
-
-
+
+
The best way to add Pulse to your Next.js application is using the built-in next/script component.
-
+
Using App Router (Recommended)
diff --git a/app/integrations/page.tsx b/app/integrations/page.tsx
index a1fdb17..8582f22 100644
--- a/app/integrations/page.tsx
+++ b/app/integrations/page.tsx
@@ -93,10 +93,9 @@ export default function IntegrationsPage() {
{/* * --- ATMOSPHERE (Background) --- */}
-
-
+
@@ -110,14 +109,14 @@ export default function IntegrationsPage() {
>
{/* * --- Title with count badge --- */}
-
+
Integrations
{integrations.length}+
-
+
Connect Pulse with {integrations.length}+ frameworks and platforms in minutes.