This guide covers common issues specific to Prismic-powered websites. Issues often relate to Slice Machine, preview mode, and Link Resolver configuration.
Common Issues Overview
Prismic is a headless CMS, meaning most issues occur in your frontend framework implementation (Next.js, Nuxt, Gatsby, etc.). Common challenges include Slice Machine configuration, preview mode behavior, Link Resolver setup, and API query optimization.
Common Issue Categories
Performance Issues
- Slice Machine build performance
- Image optimization with Prismic CDN
- API response times
- Preview mode latency
Tracking Issues
- Analytics in preview mode
- Slice-level tracking not working
- Document ID vs UID tracking
- Link Resolver tracking gaps
Installation Problems
Slice Machine Setup Issues
Slice Machine Not Starting
Symptoms:
npm run slicemachinefails- Port already in use errors
- Slice Machine UI not loading
Common causes and solutions:
# Port conflict
Error: listen EADDRINUSE: address already in use :::9999
# Solution: Change port or kill process
npx kill-port 9999
# Or specify different port
npm run slicemachine -- --port 3000
Dependencies missing:
# Ensure Slice Machine dependencies installed
npm install --save-dev @slicemachine/adapter-next
npm install @prismicio/client @prismicio/next @prismicio/react
# Check package.json scripts
"slicemachine": "start-slicemachine"
Slices Not Appearing in Prismic
Problem: Created slices in Slice Machine but not visible in Prismic dashboard
Solution:
# Push slices to Prismic
npm run slicemachine
# In UI: Click "Push to Prismic" button
# Or use CLI
npx @slicemachine/cli push
Verify slices pushed:
- Go to Prismic dashboard
- Navigate to Custom Types
- Check if slice appears in Slice Zone
Analytics Integration Installation
Tracking Code Not Loading
Problem: Analytics script not appearing in Next.js app
Check implementation locations:
// pages/_app.js (Pages Router)
import Script from 'next/script';
export default function MyApp({ Component, pageProps }) {
return (
<>
{/* Google Analytics */}
<Script
strategy="afterInteractive"
src={`https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXXXX`}
/>
<Script id="google-analytics" strategy="afterInteractive">
{`
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'G-XXXXXXXXXX');
`}
</Script>
<Component {...pageProps} />
</>
);
}
// app/layout.js (App Router)
import Script from 'next/script';
export default function RootLayout({ children }) {
return (
<html lang="en">
<head>
<Script
strategy="afterInteractive"
src={`https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXXXX`}
/>
<Script id="google-analytics" strategy="afterInteractive">
{`
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'G-XXXXXXXXXX');
`}
</Script>
</head>
<body>{children}</body>
</html>
);
}
Configuration Issues
| Issue | Symptoms | Common Causes | Solutions |
|---|---|---|---|
| Preview Mode Tracking | Analytics firing in preview | Preview detection not implemented | Check draftMode/preview and disable tracking |
| Slice Not Rendering | Blank sections on page | Slice component not registered | Register in slices/index.js |
| Link Resolver Errors | 404s on internal links | Incorrect route mapping | Update linkResolver function |
| API Rate Limiting | Slow or failed requests | Too many API calls | Implement caching and use webhooks |
| Image Not Optimizing | Large image files | Not using Prismic Image API | Use imgix URL parameters |
| Slice Zone Empty | No slices showing | Data not passed correctly | Verify SliceZone components prop |
| Type Not Found | Build errors about types | Custom types not pulled | Run npm run slicemachine and sync |
| Preview Toolbar Missing | Can't exit preview | Toolbar script not loaded | Add PrismicPreview component |
| Wrong Repository | Content not loading | Repository name mismatch | Check PRISMIC_REPO_NAME in env |
| Access Token Issues | 401 Unauthorized | Missing or invalid token | Verify PRISMIC_ACCESS_TOKEN |
Debugging with Developer Tools
Prismic-Specific Debugging
API Request Inspection
Monitor Prismic API calls:
// Create custom client with logging
import * as prismic from '@prismicio/client';
const client = prismic.createClient('your-repo-name', {
fetch: (url, options) => {
console.log('Prismic API call:', url);
const start = performance.now();
return fetch(url, options).then(response => {
console.log(`Response time: ${performance.now() - start}ms`);
console.log('Status:', response.status);
return response;
});
}
});
Check API response:
// Log full response to debug
const page = await client.getByUID('page', 'home');
console.log('Document:', JSON.stringify(page, null, 2));
console.log('Slices:', page.data.slices);
Preview Mode Debugging
Detect and log preview state:
// Next.js Pages Router
export async function getServerSideProps({ req, preview = false }) {
console.log('Preview mode:', preview);
console.log('Preview cookies:', req.cookies);
if (preview) {
console.log('Preview data:', req.previewData);
}
return {
props: { preview }
};
}
// Next.js App Router
import { draftMode } from 'next/headers';
export default async function Page() {
const { isEnabled } = draftMode();
console.log('Draft mode enabled:', isEnabled);
return <div>Draft mode: {isEnabled ? 'ON' : 'OFF'}</div>;
}
Slice Rendering Debug
Log slice data:
// In SliceZone component
import { SliceZone } from '@prismicio/react';
import { components } from './slices';
export default function MySliceZone({ slices }) {
// Debug slices
console.log('Total slices:', slices?.length);
slices?.forEach((slice, index) => {
console.log(`Slice ${index}:`, {
type: slice.slice_type,
variation: slice.variation,
primary: slice.primary,
items: slice.items
});
});
return <SliceZone slices={slices} components={components} />;
}
Browser DevTools Inspection
Network Tab for API Calls
Check Prismic CDN requests:
- Open DevTools → Network tab
- Filter:
cdn.prismic.ioorprismic.io - Look for:
/api/v2/documents/search- API queries/api/v2/documents/- Document fetches.imgix.net- Image requests
Verify request parameters:
https://your-repo.cdn.prismic.io/api/v2/documents/search
?ref=master
&q=[[at(document.type, "page")]]
&lang=en-us
&pageSize=20
Console Debugging
Check for Prismic-related errors:
// Common errors
// "No documents found" - Check query syntax
// "Repository not found" - Verify repo name
// "Invalid token" - Check access token
// Test Prismic client
if (typeof window !== 'undefined') {
window.prismicClient = client; // Make available in console
console.log('Prismic client available at window.prismicClient');
}
Platform-Specific Challenges
Preview Mode Issues
Analytics Tracking in Preview
Problem: Preview mode visits showing in analytics
Solution - Disable tracking in preview:
// pages/_app.js
import { useRouter } from 'next/router';
import { useEffect } from 'react';
export default function MyApp({ Component, pageProps }) {
const router = useRouter();
const isPreview = pageProps.preview || false;
useEffect(() => {
if (isPreview) {
console.log('Preview mode - analytics disabled');
return;
}
// Track pageview
const handleRouteChange = (url) => {
if (typeof gtag !== 'undefined') {
gtag('config', 'G-XXXXXXXXXX', {
page_path: url,
});
}
};
router.events.on('routeChangeComplete', handleRouteChange);
return () => {
router.events.off('routeChangeComplete', handleRouteChange);
};
}, [router, isPreview]);
return (
<>
{!isPreview && (
<Script
strategy="afterInteractive"
src={`https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXXXX`}
/>
)}
<Component {...pageProps} />
</>
);
}
App Router solution:
// app/layout.js
import { draftMode } from 'next/headers';
import Analytics from './analytics';
export default function RootLayout({ children }) {
const { isEnabled } = draftMode();
return (
<html>
<body>
{!isEnabled && <Analytics />}
{children}
</body>
</html>
);
}
Preview Toolbar Not Showing
Problem: Can't exit preview mode
Solution:
// app/layout.js
import { PrismicPreview } from '@prismicio/next';
import { repositoryName } from '@/prismicio';
export default function RootLayout({ children }) {
return (
<html>
<body>
{children}
<PrismicPreview repositoryName={repositoryName} />
</body>
</html>
);
}
Slice Machine Tracking
Tracking Individual Slices
Problem: Need to track interactions with specific slices
Solution - Add data attributes:
// slices/Hero/index.js
const Hero = ({ slice }) => {
return (
<section
data-slice-type={slice.slice_type}
data-slice-variation={slice.variation}
className="hero"
>
<h1>{slice.primary.title}</h1>
<button => {
if (typeof gtag !== 'undefined') {
gtag('event', 'slice_interaction', {
slice_type: slice.slice_type,
slice_variation: slice.variation,
action: 'button_click'
});
}
}}
>
{slice.primary.button_text}
</button>
</section>
);
};
export default Hero;
Automatic slice view tracking:
// components/SliceZone.js
import { SliceZone } from '@prismicio/react';
import { components } from '../slices';
import { useEffect, useRef } from 'react';
export default function CustomSliceZone({ slices }) {
const sliceRefs = useRef([]);
useEffect(() => {
// Track visible slices
const observer = new IntersectionObserver(
(entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
const sliceType = entry.target.dataset.sliceType;
if (typeof gtag !== 'undefined') {
gtag('event', 'slice_view', {
slice_type: sliceType
});
}
observer.unobserve(entry.target);
}
});
},
{ threshold: 0.5 }
);
sliceRefs.current.forEach((ref) => {
if (ref) observer.observe(ref);
});
return () => observer.disconnect();
}, []);
return (
<div>
{slices.map((slice, index) => (
<div
key={index}
ref={(el) => (sliceRefs.current[index] = el)}
data-slice-type={slice.slice_type}
>
<SliceZone slices={[slice]} components={components} />
</div>
))}
</div>
);
}
Link Resolver Tracking
Tracking Internal vs External Links
Problem: Need to differentiate Prismic link types in analytics
Solution:
// components/PrismicLink.js
import { PrismicLink as BasePrismicLink } from '@prismicio/react';
export default function PrismicLink({ field, children, ...props }) {
const handleClick = () => {
if (typeof gtag !== 'undefined') {
gtag('event', 'link_click', {
link_type: field.link_type,
link_url: field.url || field.uid,
target: field.target
});
}
};
return (
<BasePrismicLink field={field} {...props}>
{children}
</BasePrismicLink>
);
}
Multi-Language/Locale Tracking
Tracking Different Locales
Problem: Need to track which language users view
Solution:
// pages/[lang]/[uid].js
export async function getServerSideProps({ params, locale, preview = false }) {
const client = createClient({ previewData: preview });
const page = await client.getByUID('page', params.uid, {
lang: locale
});
return {
props: {
page,
locale
}
};
}
// In component
export default function Page({ page, locale }) {
useEffect(() => {
if (typeof gtag !== 'undefined') {
gtag('config', 'G-XXXXXXXXXX', {
language: locale,
page_title: page.data.title
});
}
}, [locale, page]);
return <div>{/* page content */}</div>;
}
Error Messages and Solutions
Common Prismic Errors
"No documents found"
Error in console:
PrismicError: No documents were returned
Causes:
- Wrong document type in query
- Document not published
- Incorrect UID
- Language mismatch
Solutions:
// Check document exists
try {
const page = await client.getByUID('page', 'home');
} catch (error) {
console.error('Document not found:', error);
// Fallback or 404
}
// Query all to verify
const allDocs = await client.getAllByType('page');
console.log('Available pages:', allDocs.map(d => d.uid));
"Repository not found"
Error:
Repository not found: your-repo-name
Check environment variables:
# .env.local
PRISMIC_REPO_NAME=your-actual-repo-name
// prismicio.js
export const repositoryName = process.env.PRISMIC_REPO_NAME || 'your-repo-name';
"Invalid access token"
Error:
401 Unauthorized: Invalid access token
Solutions:
# Check token in .env.local
PRISMIC_ACCESS_TOKEN=your-access-token
# Verify token in Prismic dashboard:
# Settings → API & Security → Generate an access token
Build/Deploy Errors
"Module not found: Can't resolve 'slices'"
Error during build:
Module not found: Can't resolve '../slices'
Solution:
// Ensure slices/index.js exists and exports components
// slices/index.js
export { default as Hero } from './Hero';
export { default as TextBlock } from './TextBlock';
// Import in page
import * as slices from '../slices';
Prismic Type Generation Failures
Error:
Failed to generate types for Prismic
Solutions:
# Regenerate types
npm run slicemachine
# Or manually
npx @slicemachine/cli pull
# Check prismicio-types.d.ts generated
ls .slicemachine/
Performance Problems
Slow API Responses
Problem: Prismic API calls taking too long
Diagnosis:
const start = performance.now();
const data = await client.getAllByType('page');
console.log(`API call: ${performance.now() - start}ms`);
Solutions:
- Limit fields fetched:
const page = await client.getByUID('page', 'home', {
graphQuery: `{
page {
title
meta_description
slices {
... on hero {
non-repeat {
title
}
}
}
}
}`
});
- Implement caching:
// Simple cache
const cache = new Map();
async function getCachedDocument(type, uid) {
const key = `${type}-${uid}`;
if (cache.has(key)) {
console.log('Cache hit');
return cache.get(key);
}
const doc = await client.getByUID(type, uid);
cache.set(key, doc);
return doc;
}
- Use static generation:
// Next.js - generate at build time
export async function getStaticProps({ params }) {
const page = await client.getByUID('page', params.uid);
return {
props: { page },
revalidate: 60 // ISR - revalidate every 60 seconds
};
}
Image Optimization
Problem: Large images slowing page load
Use Prismic's imgix integration:
import { PrismicImage } from '@prismicio/react';
<PrismicImage
field={slice.primary.image}
width={800}
height={600}
imgixParams={{
fit: 'crop',
q: 80,
auto: 'format,compress'
}}
/>
Manual imgix URL:
const optimizedUrl = `${image.url}?w=800&h=600&fit=crop&q=80&auto=format,compress`;
When to Contact Support
Prismic Support
Contact Prismic support when:
- API consistently returning errors
- Slice Machine not syncing
- Repository access issues
- Billing or account problems
Support channels:
- Community forum: community.prismic.io
- Email support (paid plans)
- GitHub issues for libraries
Framework-Specific Issues
Next.js issues:
- Next.js Discord
- Next.js GitHub discussions
- Vercel support (if deploying there)
When to hire a developer:
- Complex Slice Machine implementations
- Advanced preview workflows
- Multi-language site architecture
- Custom integration requirements
- Performance optimization
- Migration from other CMS
Advanced Troubleshooting
Webhook Debugging
Test webhook delivery:
// pages/api/revalidate.js
export default async function handler(req, res) {
console.log('Webhook received:', {
method: req.method,
body: req.body,
headers: req.headers
});
// Verify secret
if (req.body.secret !== process.env.REVALIDATE_SECRET) {
return res.status(401).json({ message: 'Invalid secret' });
}
try {
// Revalidate specific path
await res.revalidate('/');
return res.json({ revalidated: true });
} catch (err) {
console.error('Revalidation error:', err);
return res.status(500).send('Error revalidating');
}
}
Type Safety with TypeScript
Generate and use types:
// Generated types
import { Content } from '@prismicio/client';
import { PageDocument } from '../prismicio-types';
// Type-safe component
const MyPage: React.FC<{ page: PageDocument }> = ({ page }) => {
// TypeScript knows exact structure
const title = page.data.title; // typed!
return <h1>{title}</h1>;
};
Related Global Guides
For platform-agnostic troubleshooting, see: