/ JS Checker Fixes / JS Syntax

How to Fix JavaScript Syntax Errors

A JavaScript syntax error breaks the entire script bundle — parser fails before any code runs, so all features depending on that bundle fail simultaneously. Causes range from a missing bracket to modern syntax (optional chaining, top-level await) that older browsers don't parse. The fix is build-time linting plus correct transpilation targets. This guide walks through audit, ESLint setup, Babel/SWC configuration, and the CI workflow that prevents recurrence. For related fixes, see the JS Checker Fixes index.

1. Get the list

Step 1
Run the JS Checker
Run the JS Checker on your domain. Filter to syntax errors. Each finding shows: source URL, error message, file name, line number, affected browser/version if available.
Step 2
Cross-reference with error monitoring
If you run Sentry, LogRocket or similar, cross-reference syntax errors against real-user sessions. You'll see which browsers and OS versions actually hit them. Often shows older iOS Safari, Samsung Internet, or legacy desktop browsers.

2. Install ESLint

ESLint catches syntax errors at the editor and build level — before they reach users.

npm install --save-dev eslint @eslint/js

// Modern flat config: eslint.config.js
import js from '@eslint/js';

export default [
  js.configs.recommended,
  {
    rules: {
      // Common rules to add
      'no-unused-vars': 'warn',
      'no-undef': 'error',
    }
  }
];

// Run
npx eslint src/

For TypeScript projects, add typescript-eslint. For React, add eslint-plugin-react.

3. Configure transpile target

Modern JS features need transpilation for older browsers. Babel and SWC both read Browserslist config to decide what to transpile.

Babel example

// babel.config.js
module.exports = {
  presets: [
    ['@babel/preset-env', {
      // Reads .browserslistrc automatically
      useBuiltIns: 'usage',
      corejs: 3
    }]
  ]
};

SWC example (faster)

// .swcrc
{
  "jsc": {
    "target": "es2017"  // or use .browserslistrc
  }
}

Browserslist drives both

# .browserslistrc
> 0.5%
last 2 versions
not dead

4. Common syntax errors and fixes

Missing bracket / parenthesis

// SyntaxError: Unexpected token
function process(items {  // missing )
  return items.map(i => i * 2);
}

// Fix: complete the bracket
function process(items) {
  return items.map(i => i * 2);
}

Optional chaining in older browsers

// Works in modern browsers, syntax error in Safari < 13.1
const name = user?.profile?.name;

// Fix: transpile via Babel/SWC OR use logical &&
const name = user && user.profile && user.profile.name;

Top-level await

// Module scope only
const data = await fetchData();  // SyntaxError if not in module

// Fix: wrap in async IIFE
(async () => {
  const data = await fetchData();
})();

Private class fields

// Modern syntax — needs transpilation for older browsers
class User {
  #password;
  setPassword(p) { this.#password = p; }
}

// Babel handles it. Verify your build targets the right browsers.

Trailing commas in function calls (older browsers)

// ES2017+ — older browsers error
fn(a, b, c,);

// Fix: transpile OR remove trailing comma
fn(a, b, c);

5. Add CI lint

# GitHub Actions
name: Lint
on: [pull_request]
jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with: { node-version: 20 }
      - run: npm ci
      - run: npx eslint src/ --max-warnings 0

Fail PRs with new ESLint errors. --max-warnings 0 also fails on warnings, useful for legacy codebases trying to clean up gradually.

6. Set up real-user error monitoring

Lab tools catch syntax errors against browsers you test. Production traffic has browsers you don't test. Real-user monitoring catches the gap.

// Sentry browser SDK
import * as Sentry from '@sentry/browser';
Sentry.init({
  dsn: 'YOUR_DSN',
  environment: 'production',
});

Sentry groups errors by stack trace, browser, OS, and frequency. Top syntax errors typically appear in the first few groups within hours of a problematic deploy.

7. Test the fix

Step 1
Build with verbose output
Run your build with verbose flag. Verify Babel/SWC is processing your source files and the output JS doesn't contain unsupported syntax for your target browsers.
Step 2
Test on target browsers
BrowserStack or Sauce Labs lets you test on real older browsers. Load your built page on Safari 14, iOS 14, etc. Check console for syntax errors.
💡 The cheapest way to prevent syntax errors is keeping your Browserslist target current and rebuilding when caniuse-lite updates. Old transpile targets ship outdated polyfills; the newest browsers might have new features that need adjusted targets.

⚙️ Re-run the JS Checker

Verify syntax errors are cleared after build and transpile fixes.

Run JS Checker →
Related Guides: JS Checker Fixes  ·  Fix Console Errors  ·  Fix Render-Blocking JS  ·  JS Checker Guide
💬 Got a problem?