Skip to content

Unexpected token '<', "<!DOCTYPE" JSON Parsing Error

This error occurs when your JavaScript code attempts to parse HTML content as JSON, typically happening in web applications that fetch data from APIs or local files. The error message indicates that the JavaScript JSON.parse() method encountered HTML syntax (<!DOCTYPE) where it expected valid JSON data.

Common Causes and Solutions

1. Incorrect API Endpoint URL

The most common cause is fetching from the wrong URL that returns HTML instead of JSON:

javascript
// ❌ Wrong - might return HTML
const response = await fetch('/api/data');

// ✅ Correct - ensure proper endpoint
const response = await fetch('http://localhost:8000/api/data');

WARNING

Always verify your API endpoints return JSON by testing them directly in the browser or using tools like Postman.

2. Path Issues with Local Files

When fetching local JSON files, incorrect relative paths can cause the server to return HTML instead:

javascript
// ❌ May not point to the correct location
fetch('data.json')

// ✅ Use correct relative path from public directory
fetch('/data/data.json')

3. Server Configuration Problems

For full-stack applications, ensure your server is properly configured:

javascript
// Server-side Express.js configuration
const express = require('express');
const path = require('path');
const app = express();

// Serve static files from React build
app.use(express.static(path.join(__dirname, 'client/build')));

// API routes should come before the catch-all route
app.get('/api/data', (req, res) => {
  res.json({ message: 'Your data here' });
});

// Catch-all handler must be last
app.get('*', (req, res) => {
  res.sendFile(path.join(__dirname, 'client/build', 'index.html'));
});

4. Missing Headers

Explicitly specify that you expect JSON responses:

javascript
const response = await fetch(url, {
  headers: {
    'Accept': 'application/json',
    'Content-Type': 'application/json'
  }
});

5. Development vs Production Issues

javascript
// During development with create-react-app
const response = await fetch('http://localhost:3001/api/data');
javascript
// In production, use relative paths or environment variables
const API_URL = process.env.REACT_APP_API_URL || '';
const response = await fetch(`${API_URL}/api/data`);

Debugging Steps

When encountering this error, follow this systematic approach:

Debugging Checklist
  1. Check the URL - Verify the endpoint in browser directly
  2. Test the response - Use console.log to see what's actually returned
  3. Validate JSON - Ensure your JSON data is properly formatted
  4. Review server routes - Confirm API endpoints are before catch-all routes
  5. Check CORS - Ensure no cross-origin issues
javascript
// Debugging example
try {
  const response = await fetch('your-endpoint');
  const text = await response.text();
  console.log('Raw response:', text); // Check what you actually received
  
  // Only parse if it's actually JSON
  if (response.headers.get('content-type')?.includes('application/json')) {
    const data = JSON.parse(text);
    return data;
  } else {
    throw new Error('Server did not return JSON');
  }
} catch (error) {
  console.error('Fetch error:', error);
}

Additional Considerations

  • Environment variables: Ensure all necessary environment variables are set for your deployment platform

  • Proxy configuration: For React apps, you might need a proxy in package.json:

    json
    {
      "proxy": "http://localhost:3001"
    }
  • Body parser middleware: If working with Express.js, ensure proper body parsing:

    javascript
    const express = require('express');
    const app = express();
    
    app.use(express.json()); // Parse JSON bodies

This error typically stems from a mismatch between what your code expects (JSON) and what the server actually returns (HTML). By methodically checking your endpoints, server configuration, and response handling, you can resolve this common issue in full-stack JavaScript applications.