inertia icon indicating copy to clipboard operation
inertia copied to clipboard

Full page reloads on form submission possible?

Open mooseh opened this issue 3 years ago • 5 comments

Versions:

  • @inertiajs/inertia version: "^0.10.0"
  • @inertiajs/inertia-vue3 version: "^0.5.1"

Describe the problem:

I am using inertia with laravel, and I am using inertia on the login page using a separate blade page like so

        Inertia::setRootView('auth');
        return Inertia::render('Auth/Login'); 

the problem is when I submit the inertia login form there is only a partial page reload via web splitting so all the assets get missed causing the next page to not render properly. I need a way of when submitting the form to perform a full reload, I have tried a few ways but they are all just so ugly as it loads twice.

here is what I have implemented but am unhappy with. is there a way of achieving this?

	this.form.post('/login', {
		onSuccess(page){
			window.location.href = page.url
			console.log(page)
		}
        }

mooseh avatar Jun 18 '22 10:06 mooseh

Hello, have you tried to use this instead of an Inertia "partial reload" redirect?

return Inertia::location($url);

from https://inertiajs.com/redirects#external-redirects

lecrackdudut avatar Jun 20 '22 22:06 lecrackdudut

Hello, have you tried to use this instead of an Inertia "partial reload" redirect?

return Inertia::location($url);

from https://inertiajs.com/redirects#external-redirects

So I have implemented this by overriding sendLoginResponse in the LoginController in laravel, and it is working very well, thankyou for your response @lecrackdudut, although this has made me achieve my goal I still feel that we should have the power to tell inertia to do a full reload without web splitting, could this be submitted as a feature request?

This is the resulting code fix below

    /**
     * Send the response after the user was authenticated.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Inertia\Inertia|\Illuminate\Http\JsonResponse
     */
    protected function sendLoginResponse(Request $request)
    {

        $request->session()->regenerate();

        $this->clearLoginAttempts($request);

        if ($response = $this->authenticated($request, $this->guard()->user())) {
            return $response;
        }

        return $request->wantsJson()
                    ? new JsonResponse([], 204)
                    : Inertia::location($this->redirectPath()); //redirect()->intended($this->redirectPath());
    }

mooseh avatar Jun 21 '22 09:06 mooseh

So you're creating an entirely separate blade view for the login page? Why?

Inertia has persistent page layouts for exactly this reason. Change the layout and put all your stuff in the <InertiaHead /> tag if you need to load extra scripts/styles.

craigrileyuk avatar Jun 30 '22 17:06 craigrileyuk

So you're creating an entirely separate blade view for the login page? Why?

Inertia has persistent page layouts for exactly this reason. Change the layout and put all your stuff in the tag if you need to load extra scripts/styles.

because the login blade only has about 2 prerequisites. the app blade has about 50.

mooseh avatar Jul 08 '22 14:07 mooseh

In case you have multiple templates, you could use versioning in your HandleInertiaRequest middleware

    public function version(Request $request) {
        return $this->rootView($request) . '-' . parent::version($request);
    }
    
    public function rootView(Request $request): string
    {
        if ($request->is(['admin', 'admin/*'])) {
            return 'admin'; // Your template here
        }

        return $this->rootView;
    }

When inertia receives the json response and sees that the version is different, it will reload the page with Inertia::location but keeping the flash bag

You could in theory do it at the same time you change the root view if you don't have this middleware

Inertia::setRootView('auth');
Inertia::version('auth-'.Inertia::getVersion());

The other way is simply not to use inertia for those requests, if you already know that the page is gonna load a different template just use window.location = '/some-path';

I do believe Inertia is missing a way to retrieve the rootView to be able to set the version based on that

Tofandel avatar Jul 19 '22 11:07 Tofandel

Hello, have you tried to use this instead of an Inertia "partial reload" redirect?

return Inertia::location($url);

from https://inertiajs.com/redirects#external-redirects

So I have implemented this by overriding sendLoginResponse in the LoginController in laravel, and it is working very well, thankyou for your response @lecrackdudut, although this has made me achieve my goal I still feel that we should have the power to tell inertia to do a full reload without web splitting, could this be submitted as a feature request?

This is the resulting code fix below

    /**
     * Send the response after the user was authenticated.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Inertia\Inertia|\Illuminate\Http\JsonResponse
     */
    protected function sendLoginResponse(Request $request)
    {

        $request->session()->regenerate();

        $this->clearLoginAttempts($request);

        if ($response = $this->authenticated($request, $this->guard()->user())) {
            return $response;
        }

        return $request->wantsJson()
                    ? new JsonResponse([], 204)
                    : Inertia::location($this->redirectPath()); //redirect()->intended($this->redirectPath());
    }

Instead of sendLoginResponse, you can just update authenticated method.

protected function authenticated()
{
        $path = session()->pull('url.intended', $this->redirectPath());

        return inertia()->location($path);
 }

najibu avatar Mar 07 '23 12:03 najibu

Hey! Thanks so much for your interest in Inertia.js and for sharing this issue/suggestion.

In an attempt to get on top of the issues and pull requests on this project I am going through all the older issues and PRs and closing them, as there's a decent chance that they have since been resolved or are simply not relevant any longer. My hope is that with a "clean slate" me and the other project maintainers will be able to better keep on top of issues and PRs moving forward.

Of course there's a chance that this issue is still relevant, and if that's the case feel free to simply submit a new issue. The only thing I ask is that you please include a super minimal reproduction of the issue as a Git repo. This makes it much easier for us to reproduce things on our end and ultimately fix it.

Really not trying to be dismissive here, I just need to find a way to get this project back into a state that I am able to maintain it. Hope that makes sense! ❤️

reinink avatar Jul 28 '23 01:07 reinink