Skip to content

Error in Safari when using router.get: Attempt to use history.replaceState() more than 100 times per 10 seconds #2512

@hamannjames

Description

@hamannjames

@inertiajs/vue3 Version

1.2.0

Backend stack (optional)

No response

Describe the problem

We are using inertia and implementing infinite scroll on our pages. When the user reaches the bottom of the page we trigger a fetch of new data with router.get, passing in the current url and passing in many parameters for filters, page number, etcetera:

router.get(
        url,
        {
            ...filters,
            ...encodedFilters,
            page: pageParam,
            search: searchStore.search,
            "filter[search]": searchStore.search,
            ...(sortOrder.value ? { order: sortOrder.value } : {}),
        },
        {
            only: ["list", "selectedItem"],
            preserveState: true,
            preserveScroll: true,
            onSuccess,
        },
    );

The onSuccess method updates items in an items store.

On Safari only, this produces an error:

Unhandled Promise Rejection: SecurityError: Attempt to use history.replaceState() more than 100 times per 10 seconds

I have confirmed that we are only calling the router.get method once every 5 seconds or so. At most this is getting called 10-15 times in 30 seconds. However, Safari complains about history.replaceState being called more than 100 times in 10 seconds, and the list will not load new items until an arbitrary timeout occurs.

I believe router.get is calling history.replaceState an unnecessary amount of times. Is this happening because of the items being passed as data, or other options?

Steps to reproduce

Create a page that utilizes router.get on it like the one above, which calls the current url with parameters. Example:

router.get(
        url,
        {
            ...filters,
            ...encodedFilters,
            page: pageParam,
            search: searchStore.search,
            "filter[search]": searchStore.search,
            ...(sortOrder.value ? { order: sortOrder.value } : {}),
        },
        {
            only: ["list", "selectedItem"],
            preserveState: true,
            preserveScroll: true,
            onSuccess,
        },
    );

Wrap this in another function you can call multiple times on an interval. Example:

const callGet = (pageParam) => {/*previous function*/};
let page = 1;
setInterval(() => {callGet(page++)}, 1000);

Or something similar. Try it in Safari and witness the error in the console

Metadata

Metadata

Assignees

No one assigned

    Labels

    vue 3Related to the vue 3 adapter

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions