Skip to main content

Troubleshooting Guide

Common issues and solutions for use-typewriter-animation. This guide helps you quickly resolve problems and optimize your typewriter animations.

๐Ÿšจ Common Issuesโ€‹

Animation Not Workingโ€‹

Problem: Text appears instantly without animationโ€‹

Symptoms:

  • Text shows up immediately
  • No typing animation
  • Cursor may or may not appear

Solutions:

  1. Missing Keyframes (Most Common)
// โŒ Wrong - Missing keyframes
return (
<div>
{elements}
{cursor}
</div>
);

// โœ… Correct - Include keyframes
return (
<>
<style>{keyframes}</style>
<div>
{elements}
{cursor}
</div>
</>
);
  1. Forgot to Call .start()
// โŒ Wrong - Animation never starts
useEffect(() => {
typewriter.type('Hello, World!');
}, []);

// โœ… Correct - Call start()
useEffect(() => {
typewriter.type('Hello, World!').start();
}, []);
  1. Reduced Motion Enabled
// Check if user has reduced motion preference
const { typewriter } = useTypewriter({
respectReducedMotion: true,
reducedMotionFallback: 'slow', // Try 'slow' instead of 'instant'
});

Performance Issuesโ€‹

Problem: Animation is laggy or stutteringโ€‹

Symptoms:

  • Choppy animation
  • Low frame rate
  • Browser becomes unresponsive

Solutions:

  1. Enable Virtualization for Large Text
const { typewriter } = useTypewriter({
enableVirtualization: true,
maxVisibleSegments: 100,
});
  1. Optimize Re-renders
// โŒ Wrong - Creates new object every render
const { typewriter } = useTypewriter({
typeSpeed: 50, // New object each time
});

// โœ… Correct - Stable configuration
const config = useMemo(
() => ({
typeSpeed: 50,
cursorStyle: 'bar',
}),
[]
);

const { typewriter } = useTypewriter(config);
  1. Use GPU Acceleration
const optimizedStyles = {
transform: 'translateZ(0)', // Force GPU layer
willChange: 'transform, opacity',
};

return (
<div style={optimizedStyles}>
{elements}
{cursor}
</div>
);

Memory Leaksโ€‹

Problem: Memory usage keeps increasingโ€‹

Symptoms:

  • Browser becomes slow over time
  • Memory usage grows continuously
  • Page crashes after extended use

Solutions:

  1. Proper Cleanup
useEffect(() => {
typewriter.type('Hello').start();

// โœ… Always cleanup
return () => {
typewriter.stop();
};
}, []);
  1. Remove Event Listeners
useEffect(() => {
const handleEnd = () => console.log('Done');

typewriter.on('end', handleEnd).type('Hello').start();

return () => {
typewriter.off('end', handleEnd); // Remove listener
typewriter.stop();
};
}, []);

TypeScript Errorsโ€‹

Problem: Type errors in TypeScript projectsโ€‹

Common Errors:

  1. Missing Type Imports
// โŒ Wrong - Missing types
import { useTypewriter } from 'use-typewriter-animation';

// โœ… Correct - Import types
import { useTypewriter, UseTypewriterOptions, TypewriterState } from 'use-typewriter-animation';
  1. Incorrect Option Types
// โŒ Wrong - Invalid cursor style
const options = {
cursorStyle: 'invalid', // Type error
};

// โœ… Correct - Valid cursor style
const options: UseTypewriterOptions = {
cursorStyle: 'bar', // 'bar' | 'block' | 'underline'
};

React Strict Mode Issuesโ€‹

Problem: Animation runs twice in developmentโ€‹

Symptoms:

  • Animation plays twice
  • Only happens in development
  • Works fine in production

Solution:

// โœ… Handle Strict Mode properly
useEffect(() => {
let cancelled = false;

const runAnimation = async () => {
if (cancelled) return;

typewriter.type('Hello, World!').start();
};

runAnimation();

return () => {
cancelled = true;
typewriter.stop();
};
}, []);

๐Ÿ”ง Debugging Toolsโ€‹

Debug Modeโ€‹

Enable debug logging:

const { typewriter, state, metrics } = useTypewriter({
// Enable debug mode (if available)
debug: process.env.NODE_ENV === 'development',
});

// Log state changes
useEffect(() => {
console.log('Typewriter state:', state);
}, [state]);

// Log performance metrics
useEffect(() => {
console.log('Performance metrics:', metrics);
}, [metrics]);

Performance Monitoringโ€‹

Monitor performance in real-time:

function DebugTypewriter() {
const { typewriter, elements, cursor, metrics } = useTypewriter();
const [debugInfo, setDebugInfo] = useState({});

useEffect(() => {
const interval = setInterval(() => {
setDebugInfo({
memory: performance.memory?.usedJSHeapSize || 0,
timing: performance.now(),
segments: metrics.totalSegments,
fps: metrics.animationFrameRate,
});
}, 1000);

return () => clearInterval(interval);
}, [metrics]);

return (
<div>
<div>
{elements}
{cursor}
</div>

{/* Debug Panel */}
<div
style={{
position: 'fixed',
top: 0,
right: 0,
background: 'rgba(0,0,0,0.8)',
color: 'white',
padding: '1rem',
fontSize: '0.8rem',
fontFamily: 'monospace',
}}
>
<h4>Debug Info</h4>
<div>Memory: {(debugInfo.memory / 1024 / 1024).toFixed(2)}MB</div>
<div>Segments: {debugInfo.segments}</div>
<div>FPS: {debugInfo.fps}</div>
<div>Virtualized: {metrics.isVirtualized ? 'Yes' : 'No'}</div>
</div>
</div>
);
}

React DevToolsโ€‹

Use React DevTools Profiler:

import { Profiler } from 'react';

function ProfiledTypewriter() {
const onRender = (id, phase, actualDuration, baseDuration, startTime, commitTime) => {
console.log('Render performance:', {
id,
phase,
actualDuration,
baseDuration,
startTime,
commitTime,
});
};

return (
<Profiler id='typewriter' onRender={onRender}>
<YourTypewriterComponent />
</Profiler>
);
}

๐ŸŒ Browser Compatibilityโ€‹

Supported Browsersโ€‹

BrowserVersionNotes
Chrome88+Full support
Firefox85+Full support
Safari14+Full support
Edge88+Full support
iOS Safari14+Full support
Android Chrome88+Full support

Polyfillsโ€‹

For older browsers, you may need polyfills:

// Install polyfills
npm install core-js

// In your app entry point
import 'core-js/stable';
import 'regenerator-runtime/runtime';

Feature Detectionโ€‹

Check for required features:

function FeatureCheck() {
const [supported, setSupported] = useState(true);

useEffect(() => {
const checks = [
'IntersectionObserver' in window,
'requestAnimationFrame' in window,
'matchMedia' in window,
];

setSupported(checks.every(Boolean));
}, []);

if (!supported) {
return <div>Your browser doesn't support all required features.</div>;
}

return <YourTypewriterComponent />;
}

๐Ÿ“ฑ Mobile Issuesโ€‹

Touch Eventsโ€‹

Handle touch interactions:

function MobileTypewriter() {
const { typewriter, elements, cursor } = useTypewriter({
enableKeyboardControls: false, // Disable on mobile
});

const handleTouch = () => {
if (typewriter.isPaused()) {
typewriter.resume();
} else {
typewriter.pause();
}
};

return (
<div onTouchStart={handleTouch} style={{ touchAction: 'manipulation' }}>
{elements}
{cursor}
</div>
);
}

Viewport Issuesโ€‹

Handle viewport changes:

function ResponsiveTypewriter() {
const [viewport, setViewport] = useState({
width: window.innerWidth,
height: window.innerHeight,
});

useEffect(() => {
const handleResize = () => {
setViewport({
width: window.innerWidth,
height: window.innerHeight,
});
};

window.addEventListener('resize', handleResize);
return () => window.removeEventListener('resize', handleResize);
}, []);

const { typewriter, elements, cursor } = useTypewriter({
typeSpeed: viewport.width < 768 ? 60 : 40, // Slower on mobile
});

return (
<div>
{elements}
{cursor}
</div>
);
}

๐Ÿ” Common Error Messagesโ€‹

"Cannot read property 'type' of undefined"โ€‹

Cause: Trying to use typewriter before it's initialized

Solution:

// โŒ Wrong - Using typewriter immediately
const { typewriter } = useTypewriter();
typewriter.type('Hello'); // Error!

// โœ… Correct - Use in useEffect
const { typewriter } = useTypewriter();

useEffect(() => {
typewriter.type('Hello').start();
}, []);

"Maximum update depth exceeded"โ€‹

Cause: Infinite re-render loop

Solution:

// โŒ Wrong - Missing dependency array
useEffect(() => {
typewriter.type('Hello').start();
}); // No dependency array causes infinite loop

// โœ… Correct - Empty dependency array
useEffect(() => {
typewriter.type('Hello').start();
}, []); // Runs once

"Cannot read property 'matches' of null"โ€‹

Cause: matchMedia not available (older browsers)

Solution:

// Add polyfill or feature detection
const supportsMatchMedia = typeof window !== 'undefined' && 'matchMedia' in window;

const { typewriter } = useTypewriter({
respectReducedMotion: supportsMatchMedia,
});

๐Ÿงช Testing Issuesโ€‹

Jest/Testing Libraryโ€‹

Common testing problems:

// Mock matchMedia for tests
Object.defineProperty(window, 'matchMedia', {
writable: true,
value: jest.fn().mockImplementation((query) => ({
matches: false,
media: query,
onchange: null,
addListener: jest.fn(),
removeListener: jest.fn(),
addEventListener: jest.fn(),
removeEventListener: jest.fn(),
dispatchEvent: jest.fn(),
})),
});

// Mock performance API
Object.defineProperty(window, 'performance', {
writable: true,
value: {
now: jest.fn(() => Date.now()),
mark: jest.fn(),
measure: jest.fn(),
getEntriesByName: jest.fn(() => []),
},
});

Async Testingโ€‹

Test async animations:

import { waitFor } from '@testing-library/react';

test('typewriter animation completes', async () => {
render(<TypewriterComponent />);

await waitFor(
() => {
expect(screen.getByText('Hello, World!')).toBeInTheDocument();
},
{ timeout: 5000 }
);
});

๐Ÿ“‹ Diagnostic Checklistโ€‹

When troubleshooting, check these items:

โœ… Basic Setupโ€‹

  • Keyframes included in JSX
  • .start() method called
  • useEffect has proper dependencies
  • Cleanup function implemented

โœ… Performanceโ€‹

  • Virtualization enabled for large text
  • Stable configuration objects
  • GPU acceleration enabled
  • Memory leaks prevented

โœ… Accessibilityโ€‹

  • Reduced motion respected
  • ARIA attributes configured
  • Screen reader support tested
  • Keyboard controls working

โœ… Browser Supportโ€‹

  • Target browsers supported
  • Polyfills added if needed
  • Feature detection implemented
  • Mobile optimizations applied

โœ… TypeScriptโ€‹

  • Types imported correctly
  • Configuration typed properly
  • Event handlers typed
  • No type errors in build

๐Ÿ†˜ Getting Helpโ€‹

If you're still experiencing issues:

  1. Check the Examples โ†’ Example Gallery
  2. Review the API โ†’ API Reference
  3. Search Issues โ†’ GitHub Issues
  4. Create Minimal Reproduction โ†’ CodeSandbox Template
  5. Ask for Help โ†’ GitHub Discussions

Creating a Bug Reportโ€‹

Include this information:

  • Library version: npm list use-typewriter-animation
  • React version: npm list react
  • Browser/Node version: Check in DevTools
  • Minimal reproduction: CodeSandbox link
  • Expected behavior: What should happen
  • Actual behavior: What actually happens
  • Console errors: Any error messages

Remember: Most issues are configuration problems that can be solved quickly with the right approach! ๐ŸŽฏ