jedireza / hapi-react-views

:package: A hapi view engine for React components
MIT License
231 stars 33 forks source link

Push State and static files #63

Closed ThiagoMiranda closed 8 years ago

ThiagoMiranda commented 8 years ago

Hello. I'm trying to use your plugin in my app but I've came across with a question: How can I use Push state ( for React routing ) in Hapi react views?

I've tried:

        server.views({
            engines: {
                jsx: HapiReactViews
            },
            relativeTo: __dirname,
            path: 'src',
            compileOptions: {
                renderToString: true
            }
        });

        server.route({
            method: 'GET',
            path: '/{param*}',
            handler: {
                view: 'Default'
            }   
        });

and this works but all my static files ( images and styles mainly ) are transferred with the wrong Mime type.

If I use a path like this:

path: '/'

My routing works only if I initiate in the '/' URL. The navigation works but when I try to refresh inside a path ( e.g /users/1 ) it shows a 404 error. Does the best option ( and only ) would be to explicit make "several routes" for my react routes routes in my server.js? Something like:

        server.route({
            method: 'GET',
            path: '/',
            handler: {
                view: 'Default'
            }   
        });

        server.route({
            method: 'GET',
            path: '/users/{id}',
            handler: {
                view: 'Default'
            }   
        });

Thanks!

jedireza commented 8 years ago

Thanks for opening an issue.

This is a good question and one that I'll soon need to solve too 😉.

In another project of mine, with the help of inert, I define a directory handler for the path /public/{param*}. So essentially I put all my front-end assets (images/css/js) under one path.

I need to experiment with some different configurations, but I'd imagine that the specificity of the directory route handler would suffice.

jedireza commented 8 years ago

As a follow up to this, in another project I have my static assets served with the help of inert like this:

    server.route({
        method: 'GET',
        path: '/public/{param*}',
        handler: {
            directory: {
                path: 'public',
                listing: true
            }
        }
    });

Then I have a catch-all style handler that globs everything like this:

    server.route({
        method: 'GET',
        path: '/{glob*}',
        handler: internals.routeHandler
    });

Because I use a shared route handler I defined (internals.routeHandler), I'm even able to intercept requests to specific routes for special case handling (like redirecting or querying data) and then pass them back to internals.routeHandler. Similar to:

    server.route({
        method: 'GET',
        path: '/login/{glob*}',
        config: {
            auth: {
                mode: 'try',
                strategy: 'session'
            },
            plugins: {
                'hapi-auth-cookie': {
                    redirectTo: false
                }
            }
        },
        handler: function (request, reply) {

            if (request.params.glob !== 'logout' &&
                request.auth.isAuthenticated) {

                if (request.auth.credentials.user.roles.admin) {
                    return reply.redirect('/admin');
                }

                return reply.redirect('/account');
            }

            if (!request.auth.isAuthenticated) {
                request.app.headers = {
                    'x-auth-required': true
                };
            }

            internals.routeHandler(request, reply)
        }
    });

And I'm not having any MIME type issues. I hope this helps.