Port messages ignored in content scripts in macOS Sequoia

Messages intended for a port connection created in content scripts are unable to receive messages from the extension background script.

Consider a content.js and background.js with the following contents:

content.js:

const port = chrome.runtime.connect({
    name: 'TEST'
})

// THIS IS NEVER RECEIVED
port.onMessage.addListener((message) => {
    console.log('RECEIVED TEST MESSAGE', message)
})

background.js:

chrome.runtime.onConnect.addListener((port) => {
    if (port.name !== 'TEST') return

    console.log('test port connected', port)

    console.log('SENDING PORT MESSAGE')
    port.postMessage('HELLO')
})

This behavior was broken in Sequoia, Safari 18. This behavior also does not match that of Firefox and Chrome, which are able to receive port messages in content scripts.

It's also worth noting that UI documents with the same origin as the extension, such as a popup or iFrame, ARE able to use the port messaging as expected.

However, this bug is a huge regression and should really be addressed. I've already filed an issue via Apple Feedback with the ID of FB14721836, over a month ago, but never received a response. I'm posting here for more visibility and hope a fix can be included before Sequoia goes live next week.

Answered by Frameworks Engineer in 803023022

Thanks for the report. We've identified and fixed the issue based on your original Feedback Assistant submission. The background script in your attached sample posts a message immediately to the port in the connect handler (causing the bug). As a workaround, you can adjust your script to delay posting the background script message until the content script sends one first. The fix will be released as soon as possible.

Accepted Answer

Thanks for the report. We've identified and fixed the issue based on your original Feedback Assistant submission. The background script in your attached sample posts a message immediately to the port in the connect handler (causing the bug). As a workaround, you can adjust your script to delay posting the background script message until the content script sends one first. The fix will be released as soon as possible.

Thank you for addressing this, the workaround appears to fix the problem on Safari 18 / Sequoia RC.

Will this be included in the public Sequoia release next Monday, 9/16?

@tuggif

No need to remove the content script from the manifest. Here's an update to the snippets I posted that would fix the problem:

content.js:

const port = chrome.runtime.connect({
    name: 'TEST'
})

// SEND MESSAGE IMMEDIATELY
port.postMessage({type: 'ANYTHING'})

port.onMessage.addListener((message) => {
    console.log('RECEIVED TEST MESSAGE', message)
})

background.js:

let canSendMessage = false;

chrome.runtime.onConnect.addListener((port) => {
    if (port.name !== 'TEST') return

    console.log('test port connected', port)
     port.onMessage.addListener((message) => {
         // PORT RECEIVED A MESSAGE, NOW WE CAN RESPOND
         canSendMessage = true
          console.log('SENDING PORT MESSAGE')
          port.postMessage('HELLO')
      })
})
Port messages ignored in content scripts in macOS Sequoia
 
 
Q