Embedded mode

Description

Right now, in order to use Frontity, users just can install it with the Direct to Frontity installation, where they need to have two different domains, for WordPress and Frontity.

We could create a “Theme Bridge” plugin that overrides the PHP Theme and does instead an HTTP call to the Frontity server to retrieve the HTML and outputs that.

Screen Shot 2019-05-09 at 15.39.28
With this solution, you won’t need a new domain for your WordPress site, although you will still need a PHP Server for WordPress and a Node Server for Frontity.

Users should keep in mind that there is more routing involved (it goes to WordPress, then Frontity, then WordPress outputs the HTML), so they must use a cache plugin or it will be very slow. Good news is that with these approach the cache can be done with WordPress plugins, which know when to invalidate it intelligently.

User Stories

As a Frontity user
I want to manage everything under the same domain
so that my decoupled WordPress is easier to configure.

Possible solution

As mentioned before, we could create a WordPress plugin to override the PHP Theme Bridge and do an HTTP call to the Frontity serve. @luisherranz has been working on a proof of concept and it looks great so far:


There are some things to consider here, in order to fully understand it:

Deploying server.js and /static assets

Frontity users need to deploy two different things:

  1. The server, contained a the single server.js file. This generates the HTML.
  2. The static assets, contained in the /static folder. These are the client assets like JavaScript files, fonts and so on.

They can approach it in two different ways:

  • Using a Node server for both.
  • Using a serverless for the server.js and a static server for the /server assets.

In the first case, if they are using a Node server, there is no problem with the /static assets, as they are managed in the file system.

Some serverless hostings like Zeit Now also take care of the /static assets without extra configuration. Others like Amazon AWS or Google Cloud, have much cheaper serverless services (AWS Lambdas and Google Functions) but they require the configuration of a different service for the /static assets (Google Storage or Amazon S3). This means that, in this case, Frontity users can’t use the same url for both the server.js and /static.

There are different options to solve this:

  1. Add two different options for server URL and static URL, so users can differentiate if needed. The only problem with this approach is that services like Nginx redirect the static files (like JavaScript, fonts, images…) to the file system of WordPress and users have to change their default Nginx configuration to prevent this behaviour. The default Apache configuration doesn’t seem to have this problem.

  2. Embedding static assets inside serverless function. @luisherranz also worked on a proof of concept to embed all the static assets in the server.js, so users don’t need a static url. The problem with this approach is that users have to be really careful with the size of the /static folder, knowing that most of the assets should be inside WordPress, not here. You can find more info at its Feature Discussion. It has the same Nginx problem than solution 1.

  3. Change the Public Path to point to the static server, bypassing the Theme Bridge. We can set the public path on the fly so we could save it in the Theme Bridge config in WordPress. This way, Nginx would work, but it will need its own cache for these files, and WordPress plugins wouldn’t be useful in this case.

Cache

Users should use a cache system. We should provide, or at least recommend, a good way to deal with the cache of both the HTML output of WordPress and the REST API. We could create a new plugin to do so, include it directly in the Theme Bridge and make it optional, or just recommend another solution.

@luisherranz has forked the Simple Cache plugin to adapt it for serving static assets apart from HTML files, load times are minimal.

Handle 404s

One of the benefits of this approach, is that sitemaps generated from WordPress would work as the domain is always the same one. However, we have to decide how to handle the 404s.

It could happen that one page is a 404 in WordPress (because it hasn’t been created there) but not in the frontend (because it’s created directly from Frontity). For example if we create a “hardcoded” page or if we are fetching data from a different API. It’s great to have this flexibility, but ,in this case, that page created directly from Frontity wouldn’t be included in a sitemap generated from WordPress.

Users should have the same content in WordPress and in Frontity, but we should allow the other approach as well. To solve this, users can also create empty pages for the ones they are hardcoding or getting from a different API, and they would be included in the sitemaps. This is something WooCommerce is doing and it could work.

From the Theme Bridge perspective, our first idea is to add a setting where users can select between two options:

  • All the content not included in WordPress must return a 404 in Frontity (default).
  • 404s are handled by Frontity and it doesn’t require to exist in Wordpress.

We could add a warning while changing the settings advising the users to create empty pages instead of handling the errors from Frontity.

Possible settings

  • Server URL / Static URL: As explained before, sometimes users may need to differentiate between the server URL and the /static assets. This setting would be the one connecting Frontity with WordPress.
  • Cache: Maybe this should be handled by another plugin, but if we integrate this in the Theme Bridge, we’d need to add a setting to activate/deactivate it.
  • Change publicPath in WordPress: As explained before, one of the options to solve the problem with the `/static/ assets could be to point the publidPath to a static server, although users would need another cache system apart from WordPress. It could be done in Frontity build if users prefer.
  • Bypass Theme Bridge: Sometimes users will want to bypass the plugin, so we should provide that option.
  • Embed statics in server.js: This wouldn’t be a setting of the plugin because it would be handled from Frontity, but it’s worth to mention it.
  • Exclude URLs: We could add this option to fallback to the PHP Theme. We were using it in the old Frontity PRO and it proved to be really useful for landing pages using plugins like Contact Form 7. Sometimes, users could find easier to use the PHP Theme, or even exclude some URLs until they fully migrate them to Frontity.
  • 404: As explained before, it could be useful to let the users if they want Frontity to bypass WordPress 404s.
  • Choose which Frontity site you want to use: This could be useful for multisite configurations. The Theme Bridge would simple add that ?name=XXX query to the request.

Apart from this, we may need to add support to configure all the settings with ENV variables.

Regarding this approach, as said below, it doesn’t work with services like Nginx. I think we should have in mind what @luisherranz explained here:

Apart from all the implementation, we’d like to know your opinion about the name of the plugin. We were thinking about using something more specific than just Theme Bridge, something like Decoupled Theme Bridge or Headless Theme Bridge.

We think that Theme should be included in the name because it’s a theme substitution.Maybe Bridge could be changed, or even use a completely different name :smile: What do you think guys?

@SantosGuillamot

I think that the “Theme Bridge” is more like a tee than a “bridge”: :sweat_smile:

image

Pros:

  • For anyone familiar with unix, tee is also a command that redirects input to another output in addition to standard output. So, that semantic similarity can help people grasp the design quicker.

Cons:

  • The metaphor is not 100% accurate, because we get the data back from our “tee”, unlike the real tee, which just redirects it to an additional output.
  • It’s really weird to pronounce “tee” because I think about a cup of tea when I say it :sweat_smile:
1 Like

Haha, nice one.

“Bridge” also has an analogy. This is what’s inside my head when I think about it :laughing:

3 Likes

About settings, I agree with you @SantosGuillamot.

This is my opinion of what should go in the MVP:

  • I think having separate server/static URLs is a must.
  • We also need a query to bypass the Theme Bridge and see the original theme. We can use that for previews as well.
  • We let Frontity manage the 404’s.
  • We recommend using our fork of Simple Cache for caching.

Later on:

  • We add the possibility to change the publicPath in Frontity.
  • We add the possibility to populate that publicPath directly from the Theme Bridge settings.
  • We add the possibility to have different sets of configurations, so people can easily switch between production, staging, local development (using ngrok is site is live). Those configurations can be changed for everyone or only for that user.
  • We add the possibility to embed the statics inside the server for people who want to use only a serverless function.
  • We add the possibility to exclude some URLs from the Theme Bridge and fallback to the PHP theme.
  • We add the option to warn the developer when a URL is a 200 in Frontity but a 404 in WordPress (so they can fix it).
1 Like

What if the theme bridge would be just an option of the main Frontity plugin?

Imagine a configuration screen that starts with these two questions:

How do you want to use Frontity?

  1. With an external domain.
  2. Substitute the PHP theme.

Then, more options appear when they choose one option or the other.

1. With an external domain

  • Enter the URL of external domain: XXX
  • What do you want to do with the WordPress front-end?
    • Show 404s.
    • Redirect to the external domain.

2. Substitute the PHP theme

  • Enter the URL of the server: XXX
  • Enter the URL of the statics: XXX
  • Do you want Frontity to bypass WordPress 404s? (danger: your sitemap won’t match)

I’m telling this because to make the preview work in the external domain mode we also need to know the URL of the external domain.

2 Likes

@SantosGuillamot and I have been taking a look at the different options to serve the static assets and we made a diagram.

External domain and Nginx/Apache file reads will be possible when we implement the publicPath option.


EDIT: I have remade the diagram: https://excalidraw.com/#json=5094249578102784,nCtvPMn8e--i6pbAOxUUGg

1 Like

After some more investigation, we think it would be also a great idea to add support to configure all the settings with ENV variables.

Regarding this, it could be a great idea, I’ll give it a thought, thanks for the suggestion Luis! I feel it could improve the user experience of linking your WordPress and Frontity and I guess that, as it’s happening with the preview, sometimes it will be better to have this in the same plugin.

This will work similarly to what we did for the CLI: Expose Frontity commands to be used programmatically

A post was split to a new topic: Frontity on WP Engine

I would like to add another setting which can be useful for multisite configurations.

  • Choose which Frontity site you want to use.

For this to work, the Theme Bridge should simply add that ?name=XXX query to the request.

I have added another FD to rename ?name= to ?frontity_name= .

1 Like

Good one! :slightly_smiling_face: I’ve added it to the opening post so we keep track there of all the possible settings.

I’m going to back off a little because it looks like this is causing some confusion when people still think about it as decoupled. I think we should choose a name that helps with that confusion.

My proposal is to use the terms:

  • Decoupled mode.
  • Embedded mode.

And tell that “Frontity supports two modes, decoupled and embedded”.

3 Likes

I agree with you @luisherranz, this is still a bit confusing. I think that your proposal would help to clarify this.

2 Likes

Thanks @pablo. I guess that nobody has additional complains, so I’m going to use these terms in the WCEU talk.

1 Like

I have moved the proof of conecpt repository to the Frontity organization in GitHub and I have:

  • Renamed it to Frontity Embedded.
  • Added a proper Readme for people that want to test it out.
  • Added support for environment variables.
  • Added a bypass for previews, that fall back to the PHP theme.

The new URL is:

6 Likes

We have added support for the post preview :tada:

You also need to update Frontity and its packages to the latest version: https://docs.frontity.org/guides/keep-frontity-updated

If you have problems or want to give feedback, please do so in the FD of the preview: WordPress preview support

Thanks!! :smile:

1 Like

In order to clarify a bit more what this Embedded Mode is, here you have some diagrams diagrams that show how this Embedded Mode works (compared to the current “Decoupled Mode”)

The current “Decoupled Mode”

This “Embedded Mode”