PhpDev.App
spatie/laravel-server-side-rendering

spatie/laravel-server-side-rendering

Stars: 638

Forks: 59

Pull Requests: 24

Issues: 71

Watchers: 21

Last Updated: 2023-02-01 20:45:32

Server side rendering JavaScript in your Laravel application

License: MIT License

Languages: PHP, JavaScript

https://sebastiandedeyne.com/posts/2018/server-side-rendering-javascript-from-php

Server side rendering JavaScript in your Laravel application

Latest Version on Packagist GitHub Workflow Status Total Downloads

Making server side rendering a bit less hard in Laravel.

<html>
    <head>
        <title>My server side rendered app</title>
        <script defer src="{{ mix('app-client.js') }}">
    </head>
    <body>
        {!! ssr('js/app-server.js') !!}
    </body>
</html>

This package is a Laravel bridge for the spatie/server-side-rendering library. Before getting started, dig through the readme to learn about the underlying concepts and caveats. This readme also assumes you already have some know-how about building server rendered JavaScript apps.

Vue and React example apps are available at spatie/laravel-server-side-rendering-examples if you want to see it in action.

Support us

We invest a lot of resources into creating best in class open source packages. You can support us by buying one of our paid products.

We highly appreciate you sending us a postcard from your hometown, mentioning which of our package(s) you are using. You'll find our address on our contact page. We publish all received postcards on our virtual postcard wall.

Installation

You can install the package via composer:

composer require spatie/laravel-server-side-rendering

The service provider and Ssr alias will be automatically registered.

You can optionally publish the config file if you want to tweak things.

php artisan vendor:publish --provider="Spatie\Ssr\SsrServiceProvider" --tag="config"

Usage

Prerequisites

First you'll need to pick an engine to execute your scripts. The server-side-rendering library ships with V8 and Node engines. By default, the package is configured to use node, since you probably already have that installed on your system.

Set up the NODE_PATH environment variable in your .env file to get started:

NODE_PATH=/path/to/my/node

You'll also need to ensure that a storage/app/ssr folder exists, or change the ssr.node.temp_path config value to something else.

If you'd rather use the V8 engine, you can skip the previous two steps. You'll need to have the v8js extension installed though.

Configuration

Besides the above, no configuration's required. If you need to tweak things anyway, the config file is well documented.

Setting up your scripts

You'll need to build two scripts: a server script and a client script. Refer to your frontend-framework-of-choice's documentation on how to build those.

mix.js('resources/js/app-client.js', 'public/js')
   .js('resources/js/app-server.js', 'public/js');

The server script should be passed to the ssr function, the client script should be loaded manually. The package assumes you're using Laravel Mix, and will resolve the path for you. You can opt out of this behaviour by setting mix to false in the config file.

{!! ssr('js/app-server.js') !!}
<script src="{{ mix('js/app-client.js') }}">

Your server script should call a dispatch function to send the rendered html back to the view. Here's a quick example of a set of Vue scripts for a server-rendered app. Read the spatie/server-side-rendering readme for a full explanation of how everything's tied together.

// resources/js/app.js

import Vue from 'vue';
import App from './components/App';

export default new Vue({
    render: h => h(App),
});
// resources/js/app-client.js

import app from './app';

app.$mount('#app');
// resources/js/app-server.js

import app from './app';
import renderVueComponentToString from 'vue-server-renderer/basic';

renderVueComponentToString(app, (err, html) => {
    if (err) {
        throw new Error(err);
    }

    dispatch(html);
});

Rendering an app in your view

The package exposes an ssr helper to render your app.

<html>
    <head>
        <title>My server side rendered app</title>
        <script defer src="{{ mix('js/app-client.js') }}"></script>
    </head>
    <body>
        {!! ssr('js/app-server.js')->render() !!}
    </body>
</html>

A facade is available too.

<html>
    <head>
        <title>My server side rendered app</title>
        <script defer src="{{ mix('js/app-client.js') }}"></script>
    </head>
    <body>
        {!! Ssr::entry('js/app-server.js')->render() !!}
    </body>
</html>

Rendering options can be chained after the function or facade call.

<html>
    <head>
        <title>My server side rendered app</title>
        <script defer src="{{ mix('js/app-client.js') }}"></script>
    </head>
    <body>
        {!! ssr('js/app-server.js')->context('user', $user)->render() !!}
    </body>
</html>

Available options are documented at spatie/server-side-rendering.

Testing

composer test

Changelog

Please see CHANGELOG for more information what has changed recently.

Contributing

Please see CONTRIBUTING for details.

Security

If you've found a bug regarding security please mail [email protected] instead of using the issue tracker.

Credits

License

The MIT License (MIT). Please see License File for more information.