BigPipe in action
Mark up what should be ajaxified, answer with an AsyncResponse and BigPipe does the rest in the browser.
- Links
- Forms
- Dialogs
- JavaScript modules
<ul class="cart">
<li id="item-123">
Headphones
<a href="#"
ajaxify="/ajax/remove.php?id=123"
rel="async">Remove</a>
</li>
</ul>
A link with rel="async" requests its ajaxify URL. The server answers with DOM operations and BigPipe applies them. No page reload, no frontend code to write.
<?php
// /ajax/remove.php
$response = new \dobron\BigPipe\AsyncResponse();
$response->remove('#item-' . $_GET['id']);
$response->appendContent(
'ul.cart',
'<li>Item removed.</li>'
);
$response->send();
<form action="/ajax/subscribe.php"
method="POST"
rel="async">
<input name="email" type="email">
<button type="submit">Subscribe</button>
</form>
<p class="status"></p>
Forms with rel="async" are submitted in the background. The response can update the page, reload it or redirect after a delay.
<?php
// /ajax/subscribe.php
$response = new \dobron\BigPipe\AsyncResponse();
$response->setContent(
'p.status',
'Thanks, check your inbox!'
);
$response->redirect('/welcome', 2000);
$response->send();
<a href="#"
ajaxify="/ajax/dialog.php"
rel="dialog">Open dialog</a>
rel="dialog" opens a dialog rendered on the server. Dialogs are Bootstrap-compatible and can be stacked on top of each other.
<?php
// /ajax/dialog.php
$response = new \dobron\BigPipe\DialogResponse();
$response->setTitle('Dialog title')
->setBody('html <strong>content</strong>')
->setFooter('<button>Close</button>')
->dialog();
$response->send();
export default function UserLoggedInAlert(username) {
alert(`Welcome, ${username}!`);
}
Call any JavaScript module straight from PHP and pass it arguments. With transport markers they can even be elements, maps or sets.
<?php
$response = new \dobron\BigPipe\AsyncResponse();
$response->bigPipe()->require(
"require('UserLoggedInAlert')",
['Marvin']
);
$response->send();
See all of them working in the demo app.
Why BigPipe?
BigPipe loads and renders the essential content first and updates only the parts of the page that change. Pages feel faster and users stay engaged.
Ajax without JavaScript
Add rel="async" to links and forms and they load in the background. The server decides what happens on the page.
DOM operations from PHP
Set, append, prepend, replace or remove content by a CSS selector with the DOMOPS API, from the backend or the frontend.
Call JavaScript modules
Require your own modules from PHP and pass them arguments. Keep the logic on the server and the behaviour in small, reusable modules.
Dialogs
Render dialogs on the server, open them with rel="dialog" and attach controllers to react to their events.
Event system
Arbiter lets modules talk to each other with a simple publish/subscribe API.
Get started in minutes
Install both packages, then wire them up in your entrypoint and layout.
composer require richarddobron/bigpipe
npm install bigpipe-util
import Primer from 'bigpipe-util/dist/Primer';
Primer();
window.require = (modulePath) => {
return modulePath.startsWith('bigpipe-util/')
? require('bigpipe-util/dist/' + modulePath.replace(/^bigpipe-util\/(src|dist)\//, '') + '.js').default
: require('./' + modulePath).default;
};
<script>
(new (require("bigpipe-util/dist/ServerJS"))).handle(<?=json_encode(\dobron\BigPipe\BigPipe::jsmods())?>);
</script>