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

[0.8.x] [inertia-helpers] add support for fallback page component in resolvePageComponent #252

Closed

Conversation

sh-sabbir
Copy link

When rendering a page using Inertia::render('PageName') if the resources/js/Pages/PageName.vue doesn't exist a blank white page is rendered with an error in the browser console.

With this PR I have added support for a default fallback component that will render in case of a missing page component.

Usage Example:
Currently in app.js we are resolving pages like this

createInertiaApp({
    title: (title) => `${title} - ${appName}`,
    resolve: (name) => resolvePageComponent(`./Pages/${name}.vue`, import.meta.glob('./Pages/**/*.vue')),
    setup({ el, App, props, plugin }) {
        return createApp({ render: () => h(App, props) })
            .use(plugin)
            .use(ZiggyVue)
            .mount(el);
    },
    progress: {
        color: '#4B5563',
    },
});

with an optional fallback parameter in resolvePageComponent, it will look like this:

    resolve: (name) => resolvePageComponent(`./Pages/${name}.vue`, import.meta.glob('./Pages/**/*.vue'), `./Pages/404.vue`),

here the third parameter can be any .vue file. If the fallback is defined but also missing it will through an error in the browser console.

Benefits:

When using dynamic routing one can now easily show an error page for missing pages when pages are mostly static

Example of dynamic routing:

Route::get('/blog/{slug}', [ToolController::class, 'show']);

Example Controller:

class ToolController extends Controller {
    public function index() {
        return Inertia::render('Blogs', []);
    }

    public function show($slug) {

        // Converting `test-url` to `TestUrl`
        $tool = explode('-', $slug);
        $toolComponent = implode('', array_map('ucfirst',$slug));

        $templateName = "Blogs/{$toolComponent}";
        return Inertia::render($templateName);
    }
}

Example Existing Page Components:

Pages/Blogs.vue
Pages/404.vue
Pages/Blogs/BlogPost1.vue
Pages/Blogs/BlogPost3.vue
Pages/Blogs/BlogPost4.vue

Example URLs:

https://example.com/blog/blog-post-1 //valid
https://example.com/blog/blog-post-2 //invalid

With the modified name resolver, the first URL will load BlogPost1.vue as it's valid. But for the second URL BlogPost2.vue is missing. So it will take the fallback file 404.vue and render that.

@timacdonald timacdonald marked this pull request as draft December 10, 2023 23:26
@timacdonald
Copy link
Member

timacdonald commented Dec 13, 2023

@sh-sabbir fancy idea.

My concern here is that you lose the error and it is silently ignored. We'd probably want it to also accept a closure that returns a view so that you can do any reporting / logging you need.

The closure should accept the name as an parameter

I could see this being nice to provide a generic error message rather than just a white screen of doom or to even return a page from a different glob pattern.

@timacdonald timacdonald force-pushed the inertia-fallback-page-component branch from 10ffea8 to 23b5b57 Compare December 14, 2023 02:26
@timacdonald
Copy link
Member

This PR now:

  1. Allows the original feature that accepted a fallback page to render.
  2. Allows a closure to be passed as the fallback to handle missing pages however you would like. This is useful if you want to perform a different glob pattern, such as when you are migrating from jsx to tsx (or the otherway). See [0.8.x] Custom PageNotFoundError for resolvePageComponent #259
  3. Provides a named error that can be caught for improved error handling. See [0.8.x] Custom PageNotFoundError for resolvePageComponent #259

@timacdonald timacdonald marked this pull request as ready for review December 14, 2023 03:16
@taylorotwell
Copy link
Member

taylorotwell commented Dec 14, 2023

Maybe a dumb question, but in your original controller example, why can't you just check if the page exists there? Do we really need to add more stuff into the Vite plugin to solve this?

Please mark as ready for review when you have responded.

@taylorotwell taylorotwell marked this pull request as draft December 14, 2023 16:22
@sh-sabbir
Copy link
Author

@taylorotwell Yes, I could have checked if the page exists within the controller for sure. but that's a very specific scenario. My initial idea behind this was to allow a proper 404 page instead of throwing a page not found error.

if I have to check the page existence within all of my controllers then we don't need this check either.

if (typeof page === 'undefined') {
        throw new Error(`Page not found: ${path}`)
}

@sh-sabbir sh-sabbir marked this pull request as ready for review December 14, 2023 16:44
@sh-sabbir
Copy link
Author

Allowing people to define a custom 404 template will save tons of time

@timacdonald
Copy link
Member

I've proposed a simpler version of this in #271

@timacdonald
Copy link
Member

I'll close this one in hopes that the other accepted.

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

Successfully merging this pull request may close these issues.

None yet

3 participants