Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add preserveUrl option. #1869

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

xiCO2k
Copy link

@xiCO2k xiCO2k commented May 1, 2024

This PR adds an option to preserve the current url.

This is specially useful when there is an infinite scroll pagination.

Before

To the infinite scrolls using Inertia we had to do something similar to this:

const allPosts = ref(props.posts.data);
const nextPageUrl = ref(props.posts.next_page_url || null);
const loading = ref(false);

const load = () => {
    if (nextPageUrl.value === null) {
        return;
    }

    loading.value = true;
    axios.get(nextPageUrl.value, {
        headers: {
            'X-Inertia': true,
            'X-Inertia-Partial-Component': 'Posts/Index',
            'X-Inertia-Partial-Data': 'posts',
            'X-Requested-With': 'XMLHttpRequest',
            'X-Inertia-Version': usePage().version,
        },
    }).then(({ data }) => {
        nextPageUrl.value = data.props.posts.next_page_url;
        allPosts.value.push(...data.props.posts.data);
        loading.value = false;
    }).catch(() => {
        loading.value = false;
        router.get(nextPageUrl.value);
    })
}

let observer;

onMounted(() => {
    observer = new IntersectionObserver(
        entries => entries.forEach(entry => entry.isIntersecting && load()),
    );

    observer.observe(document.querySelector('footer'));
});

After

This this addiction, we can take advantage of the preserveUrl option, and pass it on the router.get method, like this:

const allPosts = ref(props.posts.data);

const load = () => {
    if (props.posts.next_page_url === null) {
        return;
    }

    router.get(props.posts.next_page_url, {}, {
        preserveState: true,
        preserveScroll: true,
        preserveUrl: true,
        only: ['posts'],
        onSuccess: () => allPosts.value.push(...props.posts.data)
    })
}

onMounted(() => {
    observer = new IntersectionObserver(
        entries => entries.forEach(entry => entry.isIntersecting && load()),
    );

    observer.observe(document.querySelector('footer'));
});

Without the preserveUrl it adds the ?page=2 to the url and if the user refreshes the page it will just show the page=2 content instead of both pages.

Let me know what you guys think about this feature.

Thanks,
Francisco.

@james-em
Copy link

james-em commented May 2, 2024

@xiCO2k

Not sure if it's every getting merged because it's currently ambiguous if Inertia is still maintained, however as a workaround in the meantime I believe you could use the same After solution but simply restore the URL

// Just for reference of vars names
import { inertia, page, router } from '@inertiajs/svelte';

const currentUrl = $page.url;

// Taking you exemple here
router.get(props.posts.next_page_url, {}, {
        preserveState: true, // Already the case by default normally
        preserveScroll: true,
        only: ['posts'],
        onSuccess: () => { 
         allPosts.value.push(...props.posts.data);

         // Magic here
         window.history.replaceState({}, $page.title, currentUrl) 
        }
    })

@xiCO2k
Copy link
Author

xiCO2k commented May 2, 2024

@james-em That is good hack, but I would love to have that supported by default.

@hfoletto
Copy link

hfoletto commented May 2, 2024

I'd like to just thank you @xiCO2k for re-submitting this! I'm really looking forward to have this implemented in the package.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants