Auto-focus for input elements

Currently, the s-inputelements don’t support the auto focus attribute. However, sometimes, for example when you’re showing a search field, you do want the field to be automatically focussed.

Can we get the auto-focus to be added to all input elements?

Hey @stefan - thanks for raising this.

I did some digging here, and it looks like you can already focus these fields programmatically by calling .focus() on the element. So for something like a search field you can focus it yourself when it appears rather than relying on an attribute.

On the autofocus attribute specifically: it does work for fields that are already in the page when it first loads. The catch is the browser only applies autofocus once, right as the page loads. In an app where fields are rendered by a framework, the field usually appears a moment after that, so the attribute has nothing to act on by then. In those cases it tends to come down to when the field renders in your app rather than the components themselves.

Can you please share a bit more context about your setup?

  • Which framework you’re using (React, vanilla JS, something else)
  • Whether the field is on the page at load, or shown dynamically (like opening a modal or toggling a search bar)

With that context I should be able to better point you in the right direction.

We’re just using plain old HTML / CSS views rendered by Ruby on Rails. All server rendered (call us old fashioned ;)) and available to the browser from the 1st render. We’re not using a JavaScript framework. Programatically calling the .focus() is not really an option IMHO. It’s just a standard browser capability. Adding JavaScript to fix the lack of support should be our last resort.

As attached, you’ll see that the “autofocus” attribute doesn’t get pushed to the actual input field. It is defined on the web component, but it seems it’s an attribute that is ignored.

The fix would be to simply allow the web component to forward the autofocus attribute.

Hey @stefan - thanks for the extra detail, that really helps narrow it down.

Quick clarification on the screenshot first: the autofocus attribute sitting on the <s-text-field> host and not on the inner <input> is actually expected, and it isn’t what’s stopping the focus. The field focuses through the host’s delegatesFocus shadow root rather than copying the attribute onto the inner input, so on a plain top-level page autofocus on the host does focus the field on load. I confirmed that in a standalone test. So forwarding the attribute to the inner input wouldn’t change the outcome here.

The actual blocker is the frame your app runs in. Embedded apps render inside Shopify admin’s app frame, which is cross-origin, and Chrome only allows autofocus when the whole frame chain is same-origin with the top page. A cross-origin app frame fails that check, so the attribute is silently ignored and you get the Blocked autofocusing on a <input> element in a cross-origin subframe warning. It’s a deliberate anti-abuse policy that stops cross-origin frames grabbing focus and scroll on load, so it’s working as intended rather than a Shopify-side bug, and there’s no attribute or setting that re-enables it.

I also want to call out the .focus() route I pointed you to earlier, with one useful nuance. .focus() is blocked for a different reason than the attribute: a frame can’t pull focus to itself from script until the user has interacted with it. So it does nothing on a cold load, which is why my earlier suggestion wouldn’t help for focus-on-load. But once the user has interacted with your app at all (any click or keypress), .focus() works fine from then on, including across in-app navigations. So if your search field is revealed by a user action, like clicking a search icon, calling .focus() in that handler will focus it as expected. The only case with no path is the very first paint, before the user has touched anything.

Net: true autofocus on first load isn’t achievable inside an embedded app, and that’s a browser policy rather than something we can toggle on our side. For a search field, the most reliable pattern is to focus it on the interaction that brings it up.

I’ve also flagged this with the team internally to see whether there’s anything we can do to improve the experience here. No guarantees or timeline on that, but your report is on our radar now.

Hope this helps!