How To Fix a Handle Apostrophes Error in JavaScript String

I still remember the first time my JavaScript broke just because of a single apostrophe. I was working on a project where titles were passed from PHP into a JavaScript function, and everything worked smoothly until someone added the title “John’s Adventure”. That tiny ' caused my code to completely fail.

I’ll walk you through the original buggy code, explain why the error happens, show you the correct fix, and share some best practices I learned along the way.

The Original Code That Fail

Here’s what I started with:

<script type="text/javascript">
function open_modal_now(id,title,e){
    e.preventDefault();
    $('#someid').val(id);
    $('#anotherid').val(title);
    $('#yetanotherid').modal('show');
}
</script>

And the PHP/HTML:

<?php foreach($item as $k => $v){ ?>
<a onClick="open_modal_now(<?= $v['id']; ?>,'<?= htmlentities($v['title'],ENT_QUOTES,"UTF-8"); ?>',event);">Open Modal</a>
<?php } ?>

Why Does It Break

The problem shows up when a title contains an apostrophe. For example:

John's Adventure

When htmlentities() escapes it, it becomes &#039;. So the rendered HTML looks like this:

<a onClick="open_modal_now(15,'John&#039;s Adventure',event);">Open Modal</a>

The issue is that &#039; is valid in HTML but not inside JavaScript strings. The browser tries to interpret it literally and fails, throwing:

Uncaught SyntaxError: Unexpected identifier

The Right Fix Use json_encode()

The correct way is to use PHP’s json_encode(), which ensures values are JavaScript-safe, not just HTML-safe.

Here’s the fixed version:

<?php foreach($item as $k => $v){ ?>
<a onClick="open_modal_now(
    <?= json_encode($v['id']); ?>,
    <?= json_encode($v['title']); ?>,
    event
)">Open Modal</a>
<?php } ?>

Now the output for "John's Adventure" looks like this:

<a onClick="open_modal_now(15, 'John\'s Adventure', event)">Open Modal</a>

No syntax error
Apostrophes and quotes are escaped properly

Best Practices (What I Learn After Fixing It)

Avoid Inline JavaScript

Mixing PHP, HTML, and JavaScript in one line is messy. Instead, I moved to data-* attributes:

<?php foreach($item as $k => $v){ ?>
<a href="#" 
   class="open-modal" 
   data-id="<?= htmlspecialchars($v['id'], ENT_QUOTES, 'UTF-8'); ?>" 
   data-title="<?= htmlspecialchars($v['title'], ENT_QUOTES, 'UTF-8'); ?>">
   Open Modal
</a>
<?php } ?>

Then in JavaScript:

document.querySelectorAll('.open-modal').forEach(el => {
    el.addEventListener('click', function(e) {
        e.preventDefault();
        const id = this.dataset.id;
        const title = this.dataset.title;

        $('#someid').val(id);
        $('#anotherid').val(title);
        $('#yetanotherid').modal('show');
    });
});

No escaping headaches, much cleaner.

Show Dynamic Modal Titles

I also wanted the modal to display the selected title:

$('#yetanotherid').on('show.bs.modal', function () {
    const title = $('#anotherid').val();
    document.querySelector('#modalTitle').innerText = title;
});

Sanitize Input

For security, I added a small sanitization function:

function sanitizeInput(str) {
    return str.replace(/[&<>"']/g, function (m) {
        return ({
            '&':'&amp;',
            '<':'&lt;',
            '>':'&gt;',
            '"':'&quot;',
            "'":'&#039;'
        })[m];
    });
}

Store Data Globally if Needed

Sometimes I needed the selected item in other scripts:

window.selectedItem = { id: id, title: title };

Final Thought

That one little apostrophe taught me a big lesson: escaping matters, and context matters even more. HTML escaping (htmlentities) won’t save you inside JavaScript, but json_encode will. By switching to safer practices like using data-* attributes and separating PHP, HTML, and JS logic, I not only fixed my bug but also made my code cleaner, more secure, and easier to maintain. Now, whether a title has quotes, apostrophes, or even HTML tags, my JavaScript handles it gracefully no more late night debugging over a single character.

Related blog posts