# » Welcome to Frontity

⚠️ **Frontity Framework** [**is not under active development anymore.**](https://frontity.org/blog/frontity-is-joining-automattic/)

**The team is now working on** [**the WordPress Interactivity API**](https://make.wordpress.org/core/2024/03/04/interactivity-api-dev-note/)**. This unblocks the same UX Frontity framework enabled but directly in WordPress Core, fully compatible with the new Site Editor.**

***

## » Welcome to Frontity

**👋** Hi! Welcome to the Frontity documentation.

The Frontity documentation is distributed across three separate sites:

* [**docs.frontity.org**](https://docs.frontity.org) - Introduction, concepts and guides
* [**api.frontity.org**](https://api.frontity.org) - API Reference
* [**tutorial.frontity.org**](https://tutorial.frontity.org) - Step-by-step guide

This site (docs.frontity.org) is where you will find all the information you need to start building something awesome with Frontity.

{% hint style="info" %}
If you're new to Frontity check out the [step-by-step tutorial](https://tutorial.frontity.org/). It's the quickest way to get up to speed with Frontity.
{% endhint %}

Let's kick things off by providing you with a roadmap so that you can find your way around the documentation and zero in on the information you need right now.

### [Quick Start](/getting-started)

If you're new to Frontity then you can get started by heading over to, erm..., the [**Getting Started**](/getting-started) section.

This is where you'll find the [**Quick Start Guide**](/getting-started/quick-start-guide) that will get you up and running with Frontity quickly.

Once you've followed the Quick Start Guide and have a working Frontity installation you may want to continue learning by creating a more elaborated project with the [**step-by-step guide**](https://tutorial.frontity.org/).

### [About Frontity](/about)

To learn about what Frontity is, how it works, and what features it has, visit the [**About Frontity**](/about) section.

If you're a **developer** this section will tell you all about what Frontity is capable of and what you can do with it.

If you're a **project manager** or other **decision maker** that needs to choose or justify whether to use Frontity for your project then this section provides the information you need.

### [Core Concepts](/learning-frontity)

This section is the heart of the Frontity documentation. Once you've nailed the basics in the Getting Started section you should head over to the [**Core Concepts**](/learning-frontity) section to really dig in to the detail and learn how to work with Frontity.

### [Architecture](/architecture)

Find out about how the relationship between Frontity and WordPress is structured in the [**Architecture**](https://github.com/frontity/docs/blob/master/docs/architecture.md) section, where you will also learn about possible hosting solutions.

### [Deployment](/deployment)

Once you've completed the development of your project and have a working application that you're happy with you can learn how to deploy to live in the [**Deployment**](/deployment) section.

In particular we go into detail on how to [**deploy to Vercel**](/deployment/deploy-using-vercel), our recommended hosting platform. Why do we recommend it? Because it's serverless, cheap, includes a CDN, and is really easy to set up.

### [Isomorphic React](/isomorphic-react)

Frontity sites are [Isomorphic React](/isomorphic-react) apps which are executed both on the server-side and on the client-side. In this section you'll learn how the isomorphic approach works in Frontity and how you can customize your site accordingly.

### [Performance](/performance)

With a good [caching strategy](/performance/caching) your Frontity project can be as performant as a static site.

Also, applying mechanisms such as [Link prefetching](/performance/link-prefetching) is highly recommended to improve the perceived performance.

### [SEO](/seo)

By default, Frontity will deliver to your browser a fully populated and well-formed HTML file generated from your React code that ensures a good SEO score.

But it also allows you to optimize the SEO performance of your site and customize how your site is indexed by search engine crawlers through the use of [Header meta tags](/seo#header-meta-tags) and [`robots.txt`](/seo#robots-txt).

### [Guides](/guides)

This is where you'll find an ever-growing series of [**Guides**](/guides). Some will help you in working with Frontity. Others will give you ideas for projects and provide you with the help you need to guide you from first steps to fully working project.

This is where you can really have fun with Frontity and work toward your stretch goals.

In this section we also provide you with some foundational knowledge that will assist you when working with Frontity. So if you need a refresher, or if you're new to the topics, we have included introductions to [JavaScript/ES6](/guides/javascript-basics) and [React](/guides/react-basic) in this section.

The [troubleshooting guide](/guides/troubleshooting) is also here, for when you encounter problems. If your problem is not solved here then don't forget that you can also ask the community in the [**Frontity Community Forum**](https://community.frontity.org).

### [Contributing](/contributing)

Frontity is an open source project and welcomes contributions in all forms. The [**Contributing**](/contributing) section of the documentation will guide you whether you want to make a single contribution or whether you intend to become a fully fledged contributor to the Frontity project.

We also encourage you to join the [Community Forum](https://community.frontity.org) to share your projects and ideas with fellow users and community members. This is the best place to build new connections and get community support.

Oh, and if you haven't already, you can show your support by starring the project on [GitHub](https://github.com/frontity/frontity).


# Getting started

👋 Welcome! You've just taken your first step on the path to mastering Frontity.

Frontity is a **React-based framework** that enables you to easily build a frontend for a headless (or decoupled) WordPress site. Your WordPress site serves its data via the REST-API. Frontity framework is open source and free to use.

## Requirements

To get started with Frontity you will need:

### A WordPress installation

By default Frontity provides an [example WordPress site](https://test.frontity.org/) as the data source for every new project, so you can start working with this one.

You can also [configure your own WordPress installation](/getting-started/quick-start-guide#set-your-own-wordpress-installation) to be the data source. This can be hosted either locally on your development machine, or on a web-server. You can also use a site hosted on WordPress.com.

### Node.js

If you don't already have it you can get *Node.js* from [the official site](https://nodejs.org/). This will also install `npm` and `npx` along with Node.js.

You will use these to run Frontity commands during the set-up and development of your project.

{% hint style="info" %}
For those coming from WordPress it might be worth noting that *Frontity* runs on **Node.js**, so it needs to be deployed in a different server than your WordPress. If you want to learn more about this, visit Frontity's [GitHub repo](https://github.com/frontity/frontity#why-a-different-nodejs-server) or see the [Architecture](/architecture) section arch these docs.
{% endhint %}

To test if you have Node.js installed open your terminal and run:

```bash
node -v
```

```bash
npm -v
```


# Quick start guide

Right, let's get you set up with your very first Frontity project. This guide will take you from the very basics to feeling amazed at what you can do with Frontity!

> Please check that you meet the [**requirements**](/getting-started#requirements) before following the steps below.

{% embed url="<https://youtu.be/FCnGfYfWulA>" %}

## Getting started with Frontity

1 - **Create a new Frontity project** by entering the following command in your terminal:

```bash
npx frontity create my-first-frontity-project
```

2 - **Select a starter theme**. If it's your first time using Frontity we recommend that you select `@frontity/mars-theme` to start with.

```
? Pick a starter theme to clone: @frontity/mars-theme (recommended)
```

A directory with the same name as the project name you used will be created. It will have a structure similar to this:

```
my-first-frontity-project/
|__ node_modules/
|__ package.json
|__ frontity.settings.js
|__ favicon.ico
|__ packages/
    |__ mars-theme/
```

3 - **Run the project locally** by executing this command from the terminal:

```bash
cd my-first-frontity-project && npx frontity dev
```

A development server will be started. This server will be listening on <http://localhost:3000> and watching for any changes inside the packages directory.

4 - Now you’re **ready to make changes** to your site:

Open the project directory in your preferred code editor/IDE and try editing some of the files under `packages/mars-theme`. Each time you save a change the browser will automatically reload and display the new version as these changes are detected by the development server.

## Set your own WordPress installation

A good next step is **setting your own WordPress installation** as the data source.

You can connect your [*own WordPress site*](https://docs.frontity.org/guides/what-are-the-requisites-of-wordpress-for-frontity) to your Frontity project by [setting the `state.source.url`](https://docs.frontity.org/guides/setting-url-wordpress-source-data) property in the `frontity.settings.js` file.

```javascript
const settings = {
  ...,
  packages: [
    ...,
    {
      name: "@frontity/wp-source",
      state: {
        source: {
          // Change this url to point to your WordPress site.
          url: "https://test.frontity.org/"
        }
      }
    }
  ]
}
```

By default, `state.source.url` is set to `https://test.frontity.org/` (a demo WordPress site) but you can set this property to any valid URL pointing to a WordPress site.

{% hint style="info" %}
Setting `state.source.url` should be sufficient for most WordPress.org installations and WordPress.com plans. For specific use cases check the guide [*Setting the URL of the WordPress data source*](https://docs.frontity.org/guides/setting-url-wordpress-source-data).
{% endhint %}

> Your site at `http://localhost:3000` won't auto-update with this change as auto-updates only occur with changes to files in the packages directory, so you will need to manually refresh the page in your browser.

You should now see your own posts in the Frontity project displayed in the browser.

## What's next?

### Follow the Step-by-Step Tutorial

Frontity's primary learning resource is the [**Step-by-Step Tutorial**](https://tutorial.frontity.org). This is the perfect place to start if you're new to Frontity, or even if you've previously used Frontity but feel that your knowledge is incomplete or fragmented.

### Check Frontity's guides

There are several [**Guides**](https://docs.frontity.org/guides) that will help you in your understanding of working with Frontity, and which will also assist you in solving some of the common challenges that come up when working with Dynamic SSR (server-side Rendering) in React apps connected to WordPress.

### Check the API Reference

The main reference resource is the [**API Reference**](https://api.frontity.org). This is where you'll find detailed information about Frontity CLI, packages, plugins and themes. Once you've mastered the basics of working with Frontity this is where you're likely to spend most of your time when working on projects.

### Deploy your site

When you're done developing and are ready to launch your new site follow the instructions in the [**Deployment**](https://docs.frontity.org/deployment) section to learn how to deploy your finished Frontity site. We recommend that you start by [deploying your site to Vercel](https://docs.frontity.org/deployment/deploy-using-vercel).

### Additional resources

If demos are more your thing, a number of different Frontity projects and examples can be found on this [GitHub repository](https://github.com/frontity-demos/frontity-examples).

In addition, you can head over to Frontity's [Youtube channel](https://www.youtube.com/c/Frontity/) to watch a series of videos called [Frontity Talks](https://youtube.com/playlist?list=PLC9teX20GdrTBeOzSwE-bFW-MbBEUwowS), which are especially interesting to learn more about specific topics of Frontity.

{% hint style="info" %}
The [Frontity Community Forum](https://community.frontity.org/) is the best place to get community support while helping others with your own questions and solutions. To keep it running smoothly, we encourage you to read through this [Forum Guide](https://community.frontity.org/t/frontity-community-forum-users-guide/4399) and search the [available learning resources](https://frontity.org/learn/) before posting.
{% endhint %}


# About Frontity

## Table of Contents

* [What is Frontity?](/about#what-is-frontity)
  * [An alternative rendering engine for WordPress](/about#an-alternative-rendering-engine-for-wordpress)
* [How does Frontity work?](/about#how-does-frontity-work)
  * [Why a different Node.js server?](/about#why-a-different-node-js-server)
* [Why WordPress and React?](/about#why-wordpress-and-react)
* [Why Frontity?](/about#why-frontity)
  * [Benefits of using React and WordPress with Frontity](/about#benefits-of-using-react-and-wordpress-with-frontity)
  * [Frontity features](/about#frontity-features)
  * [Key differences from other React frameworks](/about#key-differences-from-other-react-frameworks)

## What is Frontity?

Frontity is a free and open source framework. It enables you to easily build a **React-based frontend** for a [**headless (or decoupled) WordPress**](https://www.elegantthemes.com/blog/wordpress/headless-wordpress) site. Your WordPress site serves its data via the [**REST API**](https://developer.wordpress.org/rest-api/), and the frontend that you build with Frontity consumes this data and renders it in the browser as a SPA (Single Page Application) which you can configure and style to your liking.

The above approach, as exemplified by Frontity, has many advantages. But in order to build a site in this way without Frontity there are a lot of things that developers need to learn and configure: *bundling*, *transpiling*, *routing*, *server rendering*, *retrieving data from WordPress*, *managing state*, or *managing CSS*, among many others.

Next.js and Gatsby.js are two great React frameworks that can work with WordPress in this way but none of them is exclusively focused on WordPress. Therefore, there’s still some complex configuration and additional tooling that the developer has to do.

Frontity, on the other hand, is an opinionated framework based on React and focused on WordPress. It aims to make everything simpler, even for developers who are not familiar with React:

* **Focused on WordPress**: each part of the framework has been simplified and optimized to be used with WordPress.
* **Opinionated framework**: developers don’t need to figure out or make decisions about what tools to use for things like CSS or State Management.

This means that everything is ready-to-go out of the box, so to speak, so that you can jump straight in and start creating an amazing new site with WordPress and React right away.

### An alternative rendering engine for WordPress

Frontity can also be described as an alternative rendering engine for WordPress.

Traditionally WordPress generates HTML using a theme based on **PHP** template files.

When the [**REST API**](https://developer.wordpress.org/rest-api/) was merged into core in WordPress 4.7, developers were no longer limited to the PHP rendering engine. They could query WordPress for the stored content which WordPress then sent in JSON format. The developer could then use it wherever and however they wanted. This opened up a new world of possibilities for web developers.

One of those possibilities is to create frontend sites based on React. That’s where Frontity comes into play.

## How does Frontity work?

In a Frontity project, WordPress is used as a headless or decoupled CMS, just for managing the content. Frontity uses data from the WordPress REST API and generates the final HTML that is displayed in the browser using React.

You still use your WordPress dashboard to edit and create content in exactly the same way that you are accustomed to. As you make changes content is automatically updated in your Frontity site, just as it is when using a traditional WordPress theme.

Frontity apps require both a Node.js server and a WordPress server (PHP) to run on. And there are two main Frontity Modes (architectures or configurations):

* [**Decoupled Mode**](/architecture/decoupled-mode): in this mode Frontity fetches the data from the REST API of the WordPress Server and returns the final HTML to the visitor as an Isomorphic React App.
* [**Embedded Mode**](/architecture/embedded-mode): in this mode the [Frontity Embedded Mode plugin](https://api.frontity.org/frontity-plugins/embedded-mode) replaces the PHP theme and makes a request to the Frontity server to retrieve the HTML as an Isomorphic React App, which is returned to the visitor by WordPress.

Depending on the mode used, the main domain (e.g. `www.domain.com`) will be connected either to the WordPress/PHP Server (in Embedded mode) or to the Frontity/Node.js server (in Decoupled mode).

{% hint style="info" %}
Head over to the [**Architecture**](/architecture) page to learn more about how Frontity works.
{% endhint %}

### Why a different Node.js server?

React is a JavaScript library. In order to generate HTML for site visitors or for Google AMP, the server needs to be able to run JavaScript as well.

> *In theory a PHP server can send an empty HTML file with the JavaScript files included and the visitor will see the page after the JavaScript has loaded. However, this is not a good user experience and it is certainly not recommended if your site needs to be SEO friendly and to rank in search engine listings.*

**Frontity** can be hosted either on a regular Node.js server or in a **serverless** environment. That makes it both super cheap and infinitely scalable.

## Why WordPress and React?

As at time of writing (July 2021), WordPress powers [40% of all the sites](https://w3techs.com/technologies/details/cm-wordpress) on the internet. Its market share has been growing over the last few years and it shows no sign of slowing down.

![](https://w3techs.com/diagram/history_technology/cm-wordpress)

With the shift to Gutenberg, and as the use of [headless CMS](https://css-tricks.com/what-is-a-headless-cms/) grows, the WordPress community has increasingly started considering React for their projects. Besides this, modern libraries like React are growing in popularity and becoming essential to rich user experiences.

If **WordPress** is great and **React** is too, then why not **combine** the two? Especially if you want to build a CMS-powered site with modern web development tools.

We believe this JavaScript-based approach is gaining traction in the WordPress ecosystem, so there’s no better time to start getting familiar with it.

## Why Frontity?

Going with Frontity in the stack means you get the best of WordPress and the best of React while the framework does the heavy lifting. In addition to its feature set, there are other advantages and reasons why you might want to use Frontity.

### Benefits of using React and WordPress with Frontity

#### The developer experience

Frontity requires zero setup configuration, allows you to keep the simplicity of some of the most common WordPress workflows, and includes features that typically require custom engineering such as routing, caching, and integration with third-party services like Analytics (among others).

On the other hand, because Frontity is based on React, it allows you to build great user experiences with all the tools and benefits you expect from this component-based library:

* It gives you the ability to create layouts and complex UIs using components and hooks which are highly reusable.
* React's declarative code makes the code more predictable and easier to debug.
* Having a single codebase means less code to maintain and a big advantage for performance.

The ease of getting started as well as the improved developer experience are some of the biggest benefits that you can gain from using Frontity, allowing you to save an amount of development time and resources.

#### The extensibility

Frontity has been designed to be extensible by default. Similar to how plugins work in WordPress, the framework provides a powerful and flexible package management interface that enables you to easily extend Frontity according to your project needs.

The ability to reuse [packages and themes](https://api.frontity.org/frontity-packages) across projects will also help you reduce both development and maintenance times.

#### It has a strong performance-oriented approach

Frontity’s infrastructure is designed to be as efficient and performant as possible. There are different strategies directly available with Frontity (such as WordPress data normalization, lazy loading, pre-fetching, code splitting) which you can also use to impact positively both on the performance and the UX of your projects.

Head over to the [Performance section](/performance) to learn more.

#### It’s SEO optimized

Frontity does Server Side Rendering. It uses [Isomorphic rendering](/isomorphic-react), you need a Node server to render the pages but this means the browser will get fully formed HTML for pages (ready to be indexed). This makes it optimized for search engines right out of the box.

For more fine-grained SEO control, there are Frontity packages that add support for some of the most popular WordPress SEO plugins.

#### The editing experience

Marketing and content teams like tools that help them write, create, and manage pages easily. That's why they choose WordPress.

Frontity allows them to experience no interruption to their usual WordPress publishing workflow and get their work done easily without having to rely on a technical team.

Teams can also benefit from real-time content updates (thanks to Frontity's dynamic architecture) and post preview support with Frontity's [Embedded Mode plugin](https://api.frontity.org/frontity-plugins/embedded-mode), which allows them to keep the preview mode as it currently works in WordPress. In addition, Frontity works great with Gutenberg, not only for creating new content areas but also for site-wide editing.

#### The user experience

With Frontity users get meaningful content as quickly as possible. The Hydration process enables React to take control of the app so that subsequent pages load instantaneously. This is due to pre-fetching and other strategies employed by the framework. Having pages load instantaneously helps to create a great user experience.

{% hint style="info" %}
[These diagrams](https://excalidraw.com/#json=6167540090798080,cvhnsErHXsqarOVT82YgLw) can help you understand how Frontity, a WordPress + React stack and the proper performance strategies may improve the final performance of your project (besides having a great development, content creation, and user experience) in both [Decoupled](/architecture/decoupled-mode) and [Embedded](/architecture/embedded-mode) Mode.
{% endhint %}

### Frontity features

Frontity and its extensions will help save you a lot of development time and effort, whilst also allowing you to enjoy all of the latest technology trends that come pre-configured for you out of the box. *You can check them out in more detail here:* [*Frontity Features page*](/about/frontity-features)*.*

Here are the main ones:

* [Zero setup development](/about/frontity-features#zero-setup-development)
* [Lightning-fast loading](/about/frontity-features#lightning-fast-loading)
* [Instant in-app navigation](/about/frontity-features#instant-in-app-navigation)
* [Server-side Rendering](/about/frontity-features#server-side-rendering)
* [Extensible](/about/frontity-features#less-than-greater-than-extensible)
* [Battle-tested](/about/frontity-features#battle-tested-framework)
* [Serverless and horizontal scaling](/about/frontity-features#serverless-and-horizontal-scaling)
* [First class TypeScript support](/about/frontity-features#first-class-typescript-support)
* [Support for ES6 in modern browsers](/about/frontity-features#support-for-es6-in-modern-browsers)
* [Support for Wordpress.com & WordPress.org](/about/frontity-features#support-for-wordpress-com-and-wordpress-org)
* [Support for multiple sites with a single installation](/about/frontity-features#support-for-multiple-sites-with-a-single-installation)
* [Code Splitting](/about/frontity-features#code-splitting)
* [Smallest React bundle possible](/about/frontity-features#smallest-react-bundle-possible)
* [Ready for React Concurrent and Suspense](/about/frontity-features#ready-for-react-concurrent-and-suspense)

### Key differences from other React frameworks

Frontity is in a way similar to, and can be compared with, Gatsby.js and Next.js. However, there are some key differences. These are some of the distinct advantages Frontity offers.

#### 100% focused on WordPress

This means the number of concepts that you as a developer need to learn are minimal. No complex configuration is necessary to get started, and the queries to the APIs that deliver the content are pre-configured for the things that developers most frequently need.

In short, you can spend the bulk of your time on the development requirements of the project (e.g. the theme) and less time on setting up the project or worrying about tooling and configuration.

#### Opinionated

Frontity has its own state manager and CSS in JS solution. Thanks to that developers don't have to figure out how to configure these tools, or learn other technologies such as Redux or GraphQL.

#### Extensible like WordPress

Frontity powers a very flexible extensibility pattern, more similar to that of WordPress itself, rather than that of other JavaScript frameworks. In order to add new functionality or expand the capabilities of Frontity, you can use any of the existing Frontity and npm packages without having to build them from scratch.

Moreover, Frontity themes and extensions can be activated and deactivated without code changes and are reusable across projects, helping reduce both development and maintenance times.

#### Rendered dynamically

In Frontity the HTML is rendered dynamically by a Node.js server or a serverless service. This means the HTML does not have to be rebuilt each time the content is edited or new content is published.

Frontity sites can be as fast as static sites as most of the requests are handled by [intermediate cache layers](/performance/caching). The static HTML is cached by a CDN, the same way that the dynamic HTML generated by Frontity is cached and served by a CDN.

Because of its dynamic approach, Frontity provides a great power and reliability when it comes to frequent and real-time content updates, making it a great fit for those projects with content that might change rapidly or that is expected to grow over time.

In addition:

* There is no need to learn GraphQL or the REST API. The data is available to you using Frontity's built-in State Manager.
* Frontity can output HTML suitable for Google AMP with exactly the same React codebase.

{% hint style="info" %}
If you still have any questions about Frontity, please check out the [**community forum**](https://community.frontity.org), which is packed full of answers and solutions to all sorts of Frontity questions. If you don't find what you're looking for, feel free to start a new post.
{% endhint %}


# Frontity features

Frontity framework and its extensions will help save you a lot of development time while enjoying of all of the latest technology trends, already configured for you.

Here's a list of the main features included in Frontity's core:

### **Frontity features**

* [Zero setup development](/about/frontity-features#zero-setup-development)
* [Lightning-fast loading](/about/frontity-features#lightning-fast-loading)
* [Instant in-app navigation](/about/frontity-features#instant-in-app-navigation)
* [Server-side Rendering](/about/frontity-features#server-side-rendering)
* [Extensible](/about/frontity-features#less-than-greater-than-extensible)
* [Battle-tested](/about/frontity-features#battle-tested-framework)
* [Serverless and horizontal scaling](/about/frontity-features#serverless-and-horizontal-scaling)
* [First class TypeScript support](/about/frontity-features#first-class-typescript-support)
* [Support for ES6 in modern browsers](/about/frontity-features#support-for-es6-in-modern-browsers)
* [Support for WordPress.com & WordPress.org](/about/frontity-features#support-for-wordpress-com-and-wordpress-org)
* [Support for multiple sites with a single installation](/about/frontity-features#support-for-multiple-sites-with-a-single-installation)
* [Code Splitting](/about/frontity-features#code-splitting)
* [Smallest React bundle possible](/about/frontity-features#smallest-react-bundle-possible)
* [Ready for React Concurrent and Suspense](/about/frontity-features#ready-for-react-concurrent-and-suspense)

## Frontity features

### ⚙ Zero setup development

Everything is already wired up so that you can focus on building your site and spend less time worrying about tooling and configuration: React, Webpack, Babel, Server Side Rendering, Routing, CSS-in-JS, WP REST API, TypeScript, Linting, Testing, and so on.

### 🚀 Lightning-fast loading

Frontity sends an HTML that is ready to start navigating the site, so the initial load feels almost instant. No extra assets or round trips are necessary.

This HTML is fully **functional** and **navigable** without JavaScript. Once React loads, it takes control of the app and users don’t notice any change, it is 100% transparent.

### ⚡️ Instant in-app navigation

Once React has loaded, our router prefetches other routes and data automatically. Users never have to wait when they navigate inside the app.

### 🗄 Server Side Rendering

Frontity responds with a fully populated HTML file generated with React. This reduces the time required for the first contentful paint and ensures that it is optimized for search engines.

The content is retrieved using the WordPress REST API. Once React is loaded in the browser, it takes control of the page and does its magic.

### <> Extensible

One of the most amazing things about Frontity is its extensibility, similar to that of WordPress itself. It allows you to easily add new functionality and expand the capabilities of Frontity via **npm packages** without having to create them from scratch.

Frontity packages and themes can also be activated and deactivated without code changes and are reusable across projects, helping reduce both development and maintenance times.

Check out the [API Reference docs](https://api.frontity.org/frontity-packages) to see a **full list of Frontity packages** (including themes) and learn more about the different types of packages.

Frontity themes can also use any of the 80.000 React packages currently available in npm.

### 🎖 Battle-tested framework

In 2019 the Frontity team decided to open-source the internal React framework they had been using to power large WordPress news sites for the previous few years. Used by millions of readers, Frontity is proven and ideal for building engaging frontend experiences. Learn more [here](https://frontity.org/about-us/).

### 📈 Serverless and horizontal scaling

The Frontity server is so small it suits perfectly the serverless requirements. That means infinite scaling for the frontend.

All the server code is bundled in one file, ready to work with serverless services like [Vercel](https://vercel.com/docs) (using its CLI `now`) or [AWS Lambda](https://aws.amazon.com/es/lambda/). Frontity is also prepared to scale horizontally in any Node.js server.

### {  } First class TypeScript support

Frontity has amazing TypeScript support. Actually, we like it so much that Frontity itself is built using TypeScript. But don’t worry, it’s **absolutely** optional: if you don’t know or don’t want to learn it you can use regular JavaScript without problems!

### 💻 Support for ES6 in modern browsers

Frontity generates two bundles of JavaScript:

* One in ES6 without transpilation or polyfills so it’s as small and fast as possible.&#x20;
* The other in ES5 for the old browsers that don’t support ES6.

Modern browsers that support ES6 modules will request the ES6 bundle, translating into a **reduced bundle size** and **shorter evaluation time** in the browser. This guarantees that performance is not harmed in the modern browsers while ensuring backwards compatibility with the old ones.

### 🔗 Support for WordPress.com & WordPress.org

Frontity can work with different “source” extensions. The 1.0 version includes a [`wp-source` package](https://api.frontity.org/frontity-packages/features-packages/wp-source) which works with the **REST API** of any [wordpress.com](https://developer.wordpress.com/docs/api/) and [wordpress.org](https://developer.wordpress.org/rest-api/) site. This way, whether you have a self-hosted site or it is hosted by Automattic, Frontity will suit your needs.

The framework has been designed so it can support other sources in the future (like the [GraphQL API for WordPress](https://www.wpgraphql.com/)).

### ☝️ Support for multiple sites with a single installation

This is something similar to WordPress multisite: Frontity allows you to serve any number of sites with just one installation. This can be really useful for users who manage different clients or those who want to create a network.

### 🕸 Code Splitting

Frontity uses Webpack to split the code and send the minimum code required for the app to work. It also allows developers to dynamically load components with the help of loadable-components. Learn more about this feature in the [Performance](/performance) section.

### 🌱 Smallest React bundle possible

Frontity helps build sites which are fast to deliver better user experiences. That's the reason why we have tried very hard to make the core as small as possible. It has finally been reduced by 60% and only weights 60kb (gzipped).

### ✅ Ready for React Concurrent and Suspense

The React team is working hard to release [Concurrent Mode](https://reactjs.org/docs/concurrent-mode-intro.html), which is a set of features that will improve the user experience of React apps and Frontity will be compatible with it.

{% hint style="info" %}
In addition to its feature set, there are many other reasons to use Frontity. Check them out [here](/about#why-frontity).
{% endhint %}


# Browser support

The approach adopted by Frontity is as follows:

* Prioritize the performance and user experience for the large majority of users that run modern browsers.
* Do this while keeping as much compatibility as possible for the small minority of users that still use older browsers, such as IE11.

> *"as much compatibility as possible" here means that at the very least the page loads, the content can be viewed and read, and the user can navigate to other parts of the site.*

| Platform                                               | Support                 |
| ------------------------------------------------------ | ----------------------- |
| [Browsers with Proxy](https://caniuse.com/#feat=proxy) | Full hydration          |
| Browsers without Proxy (like IE11)                     | No hydration (SSR-only) |

We don’t expect feature parity between the SSR-only version and the fully hydrated version. You can think of the SSR-only version as an alternative version of your page, without the enhanced experience provided by React.

{% hint style="warning" %}
If you need to provide the feature parity in IE11, then Frontity is probably not the best option for you.
{% endhint %}


# Get involved

We'd love for you to be part of the ever-growing Frontity community. There are a variety of different ways in which you can find information and resources about the project, discuss about it, and contribute to it.

* **Docs**: this is the place to learn how to build amazing sites with Frontity - oh look, you're already here! **😄**
* **Community Forum**: this is the best place to reach out for help and get involved with the community by sharing knowledge. But also to keep track of the work done for the framework, join public feature discussions, and give feedback. We encourage you to read through this [Forum Guide](https://community.frontity.org/t/frontity-community-forum-users-guide/4399) to learn how the Community Forum is organized and how to get the most out of it.
* **GitHub**: Frontity is an open-source project and welcomes contributions. The core project, as well as the documentation and any related tool can be found in the [Frontity](https://github.com/frontity) GitHub organization. These are the main repositories:
  * [`frontity/frontity`](https://github.com/frontity/frontity): the main repository of Frontity Framework, which contains the core of the project.
  * [`frontity/docs`](https://github.com/frontity/docs): contains the documentation available at [docs.frontity.org](http://docs.frontity.org/).
  * [`frontity/api-reference`](https://github.com/frontity/api-reference): contains the documentation available at [api.frontity.org](https://api.frontity.org/).
  * [`frontity/step-by-step-tutorial`](https://github.com/frontity/step-by-step-tutorial): contains the documentation available at [tutorial.frontity.org](https://tutorial.frontity.org/).

    Please see the [Contributing](/contributing) section to find out how you can help develop Frontity and improve its documentation.
* **Demos**: a number of different Frontity projects and examples can be found in this [GitHub repository](https://github.com/frontity-demos/frontity-examples).
* **Newsletter**: the Frontity Newsletter is designed to inform you about the latest product updates, learning resources and community news surrounding Frontity Framework. Sign up [here](https://frontity.org/newsletter/) if you don't want to miss a thing.
* [**Twitter**](https://twitter.com/frontity), [**Youtube**](https://www.youtube.com/c/Frontity/) and the [**blog**](https://frontity.org/blog/) are also pretty good places if you're looking for news, videos, and major updates about Frontity.
* **Showcase**: need some inspiration? The Frontity community is always building amazing projects, discover some of them [here](https://frontity.org/showcase/).


# Core Concepts

Frontity was designed to make it as simple as possible for developers to create sites using decoupled (or headless) WordPress.

However, in order to have the best possible experience when developing with Frontity you still need to become familiar with certain concepts.

In this **Core Concepts** section you'll learn the basic ideas that underlie a Frontity Project.

A [Frontity project](/learning-frontity/project) basically consists of several packages installed into the project's directory and which are configured in the settings file (`frontity.settings.js`). In the [**Project**](/learning-frontity/project) section you'll learn about the structure of a Frontity project and the purpose of each directory or file contained within it.

The `frontity.settings.js` file is where the Frontity project is configured. It contains the definition of, and the configuration for, each package included in the project. In the [**Settings**](/learning-frontity/settings) section you'll learn more about how to add settings for your Frontity project, to define such things as:

* how many sites are being managed by this instance of Frontity,
* the packages required by each site,
* the theme to be used,
* the URL of the WordPress data source,
* any initial data for the Frontity state,

as well as much more.

Frontity projects are built around the concept of [packages](https://api.frontity.org/frontity-packages). A package is, in essence, code that instatiates logic that can be reused across many projects. In the [**Packages**](/learning-frontity/packages) section you will find various concepts and topics related to packages, such as:

* local packages,
* directory structure,
* publishing,

and more.

Every Frontity package shares a common API which consists of these four main elements:

* [**Roots**](/learning-frontity/roots): A package in Frontity can define a `root` which is an HTML element representing the point where React is inserted for that package. This is usually only needed for Theme packages but can be defined for any package.
* [**State**](/learning-frontity/state): Frontity's State is a JavaScript object containing all the data (state) exposed by the project and its packages.
* [**Actions**](/learning-frontity/actions):  Actions are a set of functions that your package needs to work. They can also be used to expose data so that other packages can get access to that data. They can modify the state but don't return anything.
* [**Libraries**](/learning-frontity/libraries): Libraries are a set of tools that are not intended to change the state, but rather other parts of the application.

As these elements, namely the Frontity state, actions and libraries, all belong to a common space shared among all the packages in a project, each package needs to be defined under its own namespace in order to avoid conflicts. In the [**Namespaces**](/learning-frontity/namespaces) section you'll learn more about how using namespaces can make Frontity projects very flexible and extensible.

Frontity uses CSS in JS for adding styles to the React components. This approach improves the performance of Frontity sites and also makes for a better developer experience. In the [**Styles**](/learning-frontity/styles) section you can learn some of the CSS in JS concepts needed to style Frontity projects.


# 1. Project

The first thing you need to understand about Frontity is that all the code lives inside packages. There is no "app code" per se, like in other frameworks. Your final site is the combination of all your packages.

For those of you coming from WordPress, that's no surprise. All the WordPress code (except the core) is contained in either the theme or the plugins. If you come from React, this may be less intuitive, but it just means that the files of your project are always inside a **package**, either your theme or any other extension.

At this point, it is important to understand and differentiate between two types of packages:

* **Core packages**:  – `frontity` and `@frontity/core` These packages contain the core of Frontity and need to be installed in any Frontity project.
* **Frontity packages**:  – For example `@frontity/wp-source` ,  `@frontity/tiny-router` or `@frontity/my-theme` These are similar to WordPress theme and plugins. You can change them if you want, add more, create new ones...

Both core and Frontity packages are *npm packages* and need to be installed with `npm install the-package-name`. Don't worry, if you have used `npx frontity create`, the core packages were already installed for you.

The Frontity packages also need to be declared in your settings file: `frontity.settings.js`. We'll talk about the settings in detail in the next section.

## Folder Structure

If you have followed our [quick start guide](/getting-started/quick-start-guide) you probably have a new **Frontity** project. This is its folder structure:

```
/my-frontity-project
|__ frontity.settings.js
|__ package.json
|__ /node_modules
|__ /packages
    |__ /my-theme
    |__ /my-custom-extension-1
    |__ /my-custom-extension-2
```

It's important to understand each part of the project:

### The `frontity.setting.js` file

As its name suggests, this is where you define the settings for your project, the packages needed, and their own settings. You have a default configuration when you use `npx frontity create` to start a new project, but Frontity is really versatile, and there are many options. You can check them out at [the Settings page](/learning-frontity/settings), explained in detail later.

### The `/node_modules/` folder

This is the folder where all your dependencies are installed. For example, the core of Frontity (`@frontity/core`) is installed there. If you install other Frontity packages like `@frontity/tiny-router` or `@frontity/wp-source` they will be there as well.

These packages **aren't meant to be modified**, as they are dependencies. If you modify their code, your code will be overwritten when you update the dependencies. Again, it is similar to WordPress. Once you install a theme or a plugin, it is recommended to not change their code because if you update them, your changes will be lost.

If you want to change these, you should first move them to the `/packages/` folder. The code won't be update when inside this directory.

### The `/packages/` folder

This is the folder where your **local packages** live. These are the packages where you will add code and functionality to your site. It will include your theme, the Frontity packages you moved from `node_modules` folder to adapt their code, and the custom packages you create. They are core in Frontity, so they are explained in detail later at [Packages](/learning-frontity/packages).

### The `package.json` file

This is the file used for configuration in any Node.js project. There are many great articles about it like [this one](https://medium.com/beginners-guide-to-mobile-web-development/why-package-json-npm-basics-cab3e8cd150), [this one](https://flaviocopes.com/package-json/) or [this one](https://alligator.io/nodejs/package-json/), but its main purpose is to store the dependencies needed for your app to work. The basic dependencies added after a `npx frontity create` are:

* **`frontity`** : this is the main package, where we can find all the methods we might need to use during development. It's also where the CLI lives.
* **`@frontity/core`** : here is where the magic happens. Core takes care of all the bundling, rendering, merging, transpiling, serving, etc. We don't need to access it in order to develop a Frontity app.
* **`@frontity/wp-source`** : this package is the one that connects to the WordPress REST API for your site and fetches all the data needed for your Frontity theme. If you are using a different Source than WordPress, you will want to change this.
* **`@frontity/tiny-router`** : this is a small package that handles `window.history` and helps us with the routing. You can also use a different Router.
* **`@frontity/mars-theme`** : this is our starter theme, where we build our site with React, but you could install a different one.

{% code title="package.json" %}

```javascript
{
  "name": "my-frontity-project",
  ...
  "dependencies": {
    "frontity": "^1.2.2"
    "@frontity/core": "^1.1.3",
    "@frontity/wp-source": "^1.1.8",
    "@frontity/tiny-router": "^1.0.12",
    "@frontity/mars-theme": "./packages/mars-theme"
  }
}
```

{% endcode %}

As you can see, our `mars-theme` dependency has no version but a path. This is how we need to add our local packages to our `package.json` so they will be treated as if they were living in `node_modules`.

{% hint style="info" %}
If you still have any questions about how Projects work in Frontity, please check out the [**community forum**](https://community.frontity.org), which is packed full of answers and solutions to all sorts of Frontity questions. If you don't find what you're looking for, feel free to start a new post.
{% endhint %}


# 2. Settings

The first thing you should do when you start a new **Frontity** project is to configure your `frontity.settings.js` file. Let's take a look at each concept you need to understand in order to use it properly.

## Site

A **site** is a set of packages and settings. For example, this is a site:

{% code title="frontity.settings.js" %}

```javascript
export default [
  {
    name: "my-site", // The name of your site.
    state: {
      frontity: {
        url: "https://www.site.com", // Some settings.
      }
    },
    packages: [
      "@frontity/mars-theme",  // And the packages of that site.
      "@frontity/tiny-router",
      "@frontity/wp-source"
    ]
  }
]
```

{% endcode %}

## Multiple Sites

One **Frontity** installation can serve content for multiple sites. This is useful if you have severals blogs and want to manage all of them with the same installation. Both the packages and settings of each site are independent.

To distinguish between different sites, you must use a `match` setting. Each time a new request is received by **Frontity**, it tests the URL against the `match` field to know which site it should load:

```javascript
// frontity.settings.js

export default [
  {
    name: "site-1",
    match: ["https://www.site-1.com"],
    packages: [...]
  },
  {
    name: "site-2",
    match: ["https://www.site-2.com"],
    packages: [...]
  }
]
```

For example, if the URL is `https://www.site-1.com/my-post` the `"site-1"` settings are loaded and if the URL is `https://www.site-2.com/category/some-cat` the `"site-2"` settings are loaded.

**Multisites are encouraged to be defined always with a `match` property** so the internal links defined for the [`<Link>` component](https://api.frontity.org/frontity-packages/collections-packages/components#link) can be [properly processed from one site to another](https://github.com/frontity/frontity/pull/625#pullrequestreview-550228515).

A typical configuration of multisite with:

* The main site linked directly to the main domain&#x20;
* The blog site linked to a `/blog` folder below the main domain&#x20;

can be defined like this...

```javascript
// ./frontity.settings.js

export default [
  {
    name: "base", // main site
    match: "(?!\/blog)",  // whatever URL that doesn't match with "/blog" 
    ... 
  },
   {
    name: "blog", // blog site
    match: "\/blog", // whatever URL matches with "/blog" 
    ... 
  },
]
```

In development, you can access a specific site using the `?frontity_name=` query, which should match the `name` specified for your site. For example, using the `frontity.settings.js` file above, to access `site-2`, you should use:

```
https://localhost:3000/?frontity_name=site-2
```

## Packages

You can specify a different set of **packages** for each site. They can be either strings or objects:

{% code title="frontity.settings.js" %}

```javascript
export default [
  {
    packages: [
      "@frontity/mars-theme",
      "@frontity/tiny-router",
      {
        name: "@frontity/wp-source",
        active: true,
        state: {  // Some settings for this package.
          source: {
            url: "https://wp.site.com/"
          }
        }
      }
    ]
  }
]
```

{% endcode %}

As you can see, they have an `active` prop. That means you can deactivate a package without having to delete it from your settings file.

In **Frontity**, all the code is contained in packages. In a sense it is more similar to WordPress, where all the code is contained in your theme and plugins, than to other JavaScript frameworks. This is obviously on purpose, but we will explain the reasons later when we talk about packages and namespaces :)

## State

The `settings` of a Frontity project are written in the `state`.

If you come from a WordPress background, you can think of **Frontity** `state` as the database of your application. And if you come from a React background, well... it's the `state` that you usually find in Redux or MobX. That `state` is accessible by your packages at runtime.

The initial *settings* of a Frontity site can be set in the `frontity.settings.js` file

{% code title="frontity.settings.js" %}

```javascript
export default [
  {
    name: "my-site",
    state: {
      frontity: {
        url: "https://www.site.com", // Some settings of the site.
      }
    },
    packages: [
      "@frontity/mars-theme",
      "@frontity/tiny-router",
      {
        name: "@frontity/wp-source",
        state: {  // Some settings for this package.
          source: {
            url: "https://wp.site.com/"
          }
        }
      }
    ]
  }
]
```

{% endcode %}

The state is compartmentalized though namespaces. Each namespace usually corresponds to a Frontity package.

For example, our `wp-source` package uses the `source` namespace to store its settings. And our `tiny-router` package uses the `router` namespace:

In this way, we keep organized the settings of each package.

{% code title="frontity.settings.js" %}

```javascript
packages: [
  {
    name: "@frontity/tiny-router",
    state: {
      router: {
        autoFetch: true
      }
    }
  }
]
```

{% endcode %}

There's also a special namespace called `frontity` that is the place to set the general properties of our site. There's a mandatory property we need to set under the `frontity` namespace: `state.frontity.url`

### `state.frontity.url`

The important takeaway here is: *in the settings file you have the opportunity to change the `state` of **Frontity**. Most of the time you will use this to configure the settings of each package.*

{% hint style="info" %}
If you still have any questions about Settings in Frontity, please check out the [**community forum**](https://community.frontity.org), which is packed full of answers and solutions to all sorts of Frontity questions. If you don't find what you're looking for, feel free to start a new post.
{% endhint %}


# 3. Packages

## Local Packages

As we have already explained, this is the place where you will add code and functionality to your sites.

When you do a `npx frontity create`, we install three packages for you:

* `@frontity/tiny-router` as an external package. It ends up in the `node_modules` folder.
* `@frontity/wp-source` as an external package. It ends up in the `node_modules` folder.
* `@frontity/mars-theme` as a **local package**. It ends up in the `packages` folder.

We do this because the most likely situation is that you want to modify the theme, but you don't want to modify the router or source packages.

Once we move a package from `node_modules` to `packages` it becomes a **local package** and you can change it at will. If you use `git`, its code is also included in your project and you can commit any change. If you want to use that package in other projects or you want to contribute to the community, you can publish it to npm using `npm publish`.

Be aware, you should not change anything inside `node_modules` because that folder is not committed to git and it is thrown away each time you move, reinstall or deploy your project.

Finally, it's worth noting that **Frontity** doesn't know which packages are local and which are external. The only difference between them is the way they are installed in the `package.json`. When they are local, they are referenced by folder and when they are external, by the version number:

{% code title="package.json" %}

```javascript
"dependencies": {
  "frontity": "^0.2.11", // installed in node_modules
  "@frontity/core": "^0.3.7", // installed in node_modules
  "@frontity/wp-source": "^0.1.7", // installed in node_modules
  "@frontity/tiny-router": "^0.3.4", // installed in node_modules
  "@frontity/mars-theme": "./packages/mars-theme" // installed in packages
}
```

{% endcode %}

If you want to install a new Frontity package you can follow this guide: [Install a new Frontity package](/guides/install-a-new-package).

## Package Folder Structure

Packages have their own `package.json` file. Its code is inside the `/src` folder.

```
my-frontity-project/
|__ ...
|__ packages/
    |__ my-theme/
        |__ package.json
        |__ src/
            |__index.js
```

Let's review this in detail.

### Package.json

The `package.json` file is where you can write the info (name, description, author, repository, version...) of the package. It's just a regular `package.json` file, so nothing fancy here.

It also lists the npm `dependencies` for the package. The `"dependencies"` field gets automatically populated when you run `npm install some-npm-package` in the package folder.

```
cd packages/my-awesome-theme
npm install some-npm-package
```

{% code title="/packages/my-awesome-theme/package.json" %}

```javascript
{
  "name": "my-awesome-theme",
  "description": "An awesome theme for Frontity",
  ...
  "dependencies": {
    "some-npm-package": "^2.2.6"
  }
}
```

{% endcode %}

Packages need their own `package.json` file because:

* **Frontity** treats them like any other npm package found in `node_modules`.
* They can be published to npm independently  🚀
* They have their own name, version, authors and license.

### Entry Points

By default only one file is needed: `/src/index.js`.

In some cases you may want to use different code in your client than in your server. Then you can use two files, `/src/client.js` and `/src/server.js`.

## Publishing Local Packages

One thing we wanted to make sure in **Frontity** is that publishing packages was really easy.

For that reason, **Frontity** packages don't need to be transpiled. They can be written in either JavaScript or TypeScript. *So, look ma, no build step!*

They can be published to npm directly from the `/packages` folder of your **Frontity** project:

```
cd packages/my-awesome-theme
npm publish
```

Now `my-theme` is available in npm! Any other **Frontity** user can install it using:

```
npm install my-awesome-theme
```

And then including it in their `frontity.settings.js` file:

```javascript
{
  name: "my-site",
  packages: [
    "@frontity/my-awesome-theme",
    "@frontity/tiny-router",
    "@frontity/wp-source"
  ]
}
```

Yes, it is **that simple** :)

## Package exports

Packages can export any of these elements in their `index.js` file:

* **Roots:** React components that will be included in the app.
* **Fills**: React components that will be included in the app, but injected after the roots.
* **State:** A JavaScript object containing all the state exposed by your package.
* **Actions:** A set of actions that your package needs to work or expose for other packages.&#x20;
* **Libraries:** Any additional tools that your package exposes for other packages.

For example, a simple theme could be like this:

{% code title="/packages/my-awesome-theme/src/index.js" %}

```javascript
import Theme from "./components";

export default {
  roots: {
    theme: Theme // <- This is the root component of your theme.
  },
  state: {
    theme: {
      menu: [
        ["Home", "/"],
        ["About", "/about"]
      ],
      isMenuOpen: false,
      featuredImage: {
        showOnList: true,
        showOnPost: false
      }
    }
  },
  actions: {
    theme: {
      openMenu: ({ state }) => {
        state.theme.isMenuOpen = true;
      },
      closeMenu: ({ state }) => {
        state.theme.isMenuOpen = false;
      }
    }
  }
}
```

{% endcode %}

By the way, it's probably good to point out here that in Frontity all packages are equal. Frontity doesn't know which one represents a `theme` or which one represents a `source`. It treats all of them equally.

Let's explore the **Roots** and **Fills** in the next section.

{% hint style="info" %}
If you still have any questions about Packages in Frontity, please check out the [**community forum**](https://community.frontity.org), which is packed full of answers and solutions to all sorts of Frontity questions. If you don't find what you're looking for, feel free to start a new post.
{% endhint %}


# 4. Roots

## Roots

Each package has the opportunity to include any number of React nodes in the final HTML.

We finished the [Packages](/learning-frontity/packages) section with an example of package export that contained a `root` like this:

{% code title="/packages/my-awesome-theme/src/index.js" %}

```javascript
import MyAwesomeTheme from "./components";

export default {
  roots: {
    theme: MyAwesomeTheme,
  },
};
```

{% endcode %}

Usually, a React app injects it's code in a `<div>` of the body, like this:

{% code title="/index.HTML (rendered by Frontity)" %}

```markup
<html>
  <head>...</head>
  <body>
    <div id="root">
      <!-- REACT IS INJECTED HERE -->
    </div>
  </body>
</html>
```

{% endcode %}

**Frontity** uses that `<div id="root">` to inject the roots of all the packages that are installed:

{% code title="/index.HTML (rendered by Frontity)" %}

```jsx
<html>
  <head>...</head>
  <body>
    <div id="root">
      <MyAwesomeTheme />
      <ShareModal />
      <YetAnotherPackage />
    </div>
  </body>
</html>
```

{% endcode %}

Most of the time only your `theme` will export a **root**, but if any other package needs something in the DOM, it can include it also. For example, let's imagine a *ShareModal* package that has a modal like this:

![](https://frontity.org/wp-content/uploads/2021/04//screenshot-blog-mobile-share.jpg)

This package can export the React elements it needs in its **root** and expose an action like `actions.share.openModal()` to interact with the theme.

The **root** could be something like this:

{% code title="/packages/my-share-modal-package/src/components/index.js" %}

```jsx
const ShareRoot = ({ state }) => state.share.isModalOpen && <ShareModal />;
export default ShareRoot;
```

{% endcode %}

And the rest of the package something like this:

{% code title="/packages/my-share-modal-package/src/index.js" %}

```javascript
import ShareRoot from "./components/";

export default {
    roots: {
        share: ShareRoot
    },
    state: {
        share: {
            isModalOpen: false
        }
    },
    actions: {
        share: {
            openModal: ({ state }) => {
                state.share.isModalOpen = true;
            },
            closeModal: ({ state }) => {
                state.share.isModalOpen = false;
            }
        }
    }
}
```

{% endcode %}

Then the only thing the theme would have to do if they want to include share functionality is to check if there's a `share` package and if there is, use its `actions.share.openModal()` action when appropriate. For example in these buttons:

![](https://frontity.org/wp-content/uploads/2021/04//screenshot-mobile-share.jpg)

I hope you're starting to see how extensibility works in **Frontity**, but don't worry too much now, we'll talk in more detail later.

By the way, **Frontity** has an API to modify the `<head>` element inside React using the `<Head>` component like this:

```jsx
import { Head } from "frontity";

const MyPackage = () => (
  <Head>
    <title>The title of the page</title>
    <link rel="canonical" href="http://mysite.com/example" />
    <meta name="description" content="Some description" />
  </Head>
);
```

So even though **Frontity** only allows packages to insert React nodes in the `<div id="root">` of the body, they can also modify the `<head>` by adding tags inside a `<Head>`.

For a more detailed explanation you can check [Head page](broken://pages/-M3z_PfNSKt4vGA-7_6t).

{% hint style="info" %}
If you still have any questions about Roots in Frontity, please check out the [**community forum**](https://community.frontity.org), which is packed full of answers and solutions to all sorts of Frontity questions. If you don't find what you're looking for, feel free to start a new post.
{% endhint %}


# 5. State

The next thing we should look at is the `state`.

We have defined it previously as ***"**&#x41; JavaScript object containing all the state exposed by your package"*. For example:

{% code title="/packages/my-awesome-theme/src/index.js" %}

```javascript
export default {
  state: {
    theme: {
      menu: [
        ["Home", "/"],
        ["About", "/about"],
      ],
      featuredImage: {
        showOnList: true,
        showOnPost: false,
      },
      isMenuOpen: false,
    },
  },
};
```

{% endcode %}

As you can see here, this theme needs some settings like the `menu` or settings to define if it should show featured images or not, and then some state that is useful while the app is running, like `isMenuOpen`.

You can access the state in the client console with:

```
> frontity.state
```

State is a proxy, so you can see the original object clicking on `[[Target]]` :

![Expand \[\[Target\]\] to see the real object behind the proxy.](https://frontity.org/wp-content/uploads/2021/04//state-is-a-proxy.png)

## Why not separate settings and state?

First, here at Frontity we think the less concepts the better. Second, imagine a `notifications` package wants to add an item to the `menu` only when the browser actually supports notifications. That's super easy to do by just using the `state`:

{% code title="/packages/my-notifications-package/src/index.js" %}

```javascript
export default {
  actions: {
    notifications: {
      init: ({ state }) => {
        // Only run this in the browser:
        if (state.frontity.platform === "client") {
          // Only add item to the menu if browser support notifications:
          if ("Notification" in window) {
            state.theme.menu.push(["Notifications", "/notification-settings"]);
          }
        }
      }
    }
  }
```

{% endcode %}

As you can see, packages can access the state exposed by other packages.

Finally, what if you decide that the app should be run with the menu open by default? Then you'd only have to set `isMenuOpen` to `true` in your `frontity.settings.js` file. Yes, I know, that makes no sense, but I hope it gives you a sense of how flexible this pattern is.

Another good example of `state` is `tiny-router`. It exposes three props:

{% code title="/packages/tiny-router/src/index.js" %}

```javascript
export default {
  state: {
    router: {
      link: "/",
      autoFetch: true,
    },
  },
};
```

{% endcode %}

Here `link` represents the current URL of your app and it changes when you use the action `actions.router.set("/other-url")`in your theme.

If we were to create an analytics package, we could use `state.router.link` when sending pageviews:

{% code title="/packages/my-analytics-package/src/index.js" %}

```javascript
export default {
  actions: {
    analytics: {
      sendPageView: ({ state }) => {
        ga('send', {
          hitType: 'pageview',
          page: state.router.link
        });
      }
    }
  }
```

{% endcode %}

Finally, `tiny-router` exposes a third prop called `autoFetch`. This is a setting and, by default, is `true`. If it's active, it fetches the data you need each time you navigate to a new route using: `actions.router.set(link)`.

Here the most common scenario is that you will use your `frontity.settings.js` file to set `autoFetch` to `false` when you want to control the fetching yourself:

{% code title="frontity.settings.js" %}

```javascript
export default {
  packages: [
    ...,
    {
      name: "@frontity/tiny-router",
      state: {
        router: {
          autoFetch: false,
        },
      },
    },
  ],
};
```

{% endcode %}

These are the most important things you need to know about the **Frontity** state:

## 1. State should be serializable

Only objects, arrays and primitives (strings, numbers...) are allowed in the `state` because it must be serializable. No circular dependencies are allowed either. The best way to think about it is: **it's a JSON**.

Actually, it is converted to a JSON when it's sent to the client. We'll talk later about how server-side Rendering works, but it is something like this:

![](https://frontity.org/wp-content/uploads/2021/04//server-side-client-side.png)

First, this is what Frontity does in the server:

1. It gets the settings of the current site from `frontity.settings.js`.
2. It merges the state exposed by each package with the state from `frontity.settings.js`.
3. It gives each package the opportunity to populate `state` with an async `beforeSSR` action. SSR stands for server-side Rendering. This is usually used to fetch content from the WP REST API.
4. It renders React using that initial state.
5. It sends both the HTML generated by React and the initial state to the client.

The client browser paints the HTML received from the server. Then, this is what Frontity does once the JavaScript is run:

1. It loads the `state` in the client using the initial state received from the server. This guarantees that when we render React again we will be in the very same place where we left on the server.
2. It renders React again. It should produce the very same HTML we've sent from the server.
3. It gives each package the opportunity to run code with an `afterCSR` action. CSR stands for client-side Rendering.

## 2. All the state is merged together

As we've seen in the previous point, the states from `frontity.settings.js` and your packages are merged together.

Let's imagine we have this setting file:

{% code title="frontity.settings.js" %}

```javascript
export default {
  state: {
    frontity: {
      url: "https://my-site.com",
    },
  },
  packages: [
    "@frontity/wp-source",
    {
      name: "@frontity/my-awesome-theme",
      state: {
        theme: {
          featuredImage: {
            showOnList: true,
          },
        },
      },
    },
    {
      name: "@frontity/tiny-router",
      state: {
        router: {
          autoFetch: false,
        },
      },
    },
  ],
};
```

{% endcode %}

First, the states from `my-awesome-theme`, `tiny-router` and `wp-source` get merged:

{% code title="" %}

```javascript
state: {
  theme: {
    isMenuOpen: false,
    featuredImage: {
      showOnList: false,
      showOnPost: false
    }
  },
  router: {
    link: "/",
    autoFetch: true,
  },
  source: {
    data: {},
    post: {},
    ... // source contains more objects for categories, tags, pages...
  }
}
```

{% endcode %}

Then, the state from `frontity.settings.js` file gets merged:

{% code title="" %}

```javascript
state: {
  frontity: {
    url: "https://my-site.com", // <- this was added in frontity.settings.js
  },
  theme: {
    isMenuOpen: false,
    featuredImage: {
      showOnList: true, // <- this was modified in frontity.settings.js
      showOnPost: false
    }
  },
  router: {
    link: "/",
    autoFetch: false, // <- this was modified in frontity.settings.js
  },
  source: {
    data: {},
    post: {},
    ...
  }
}
```

{% endcode %}

Then Frontity executes `beforeSSR` to give each package the opportunity to modify the state. For example, the theme could use it to fetch content from the REST API:

{% code title="/packages/my-awesome-theme/src/index.js" %}

```javascript
actions: {
  theme: {
    beforeSSR: async ({ state, actions }) => {
      await actions.source.fetch(state.router.link);
    };
  }
}
```

{% endcode %}

This populates `source` with some data. For example, if the URL is `/my-post`:

{% code title="" %}

```javascript
state: {
  ...,
  source: {
    data: {
      "/my-post": {
        type: "post",
        id: 123,
        isPost: true
      }
    },
    post: {
      123: {
        id: 60,
        date: "2016-11-25T18:31:11",
        title: "..."
        content: "..."
        ...
      }
    },
    ...
  }
}
```

{% endcode %}

Now everything is ready for the React render in the server!

## 3. State should be minimal

There are two reasons for this:

1. The initial state is sent to the client, so the smaller the better.
2. It's easier to cause out-of-sync bugs when the state exists in two different places.

For that reason, Frontity supports **derived state**.

Remember I told you that `state` must be serializable and cannot contain functions? Well, that's still technically true, but you can include **derived state** functions. Let's take a look at an example:

```javascript
state: {
  share: {
    data: {
      "/my-first-post": {
        "facebook": 15,
        "twitter": 12,
      },
      "/my-second-post": {
        "facebook": 25,
        "twitter": 32,
      }
    },
    totalCount: 84
    ...
  }
}
```

Here we have a `totalCount` field that represents the sum of all the shares we have in our posts. It looks great, but what happens if we update the shares of our second post?

```javascript
state: {
  share: {
    data: {
      "/my-first-post": {
        "facebook": 15,
        "twitter": 12,
      },
      "/my-second-post": {
        "facebook": 43,
        "twitter": 64,
      }
    },
    totalCount: 84 // <- now totalCount is out of sync
    ...
  }
}
```

Wouldn't it be much easier if `totalCount` could be calculated reactively each time their dependencies change? That's precisely what **derived state** is for:

```javascript
state: {
  share: {
    data: {
      "/my-first-post": {
        "facebook": 15,
        "twitter": 12,
      },
      "/my-second-post": {
        "facebook": 43,
        "twitter": 64,
      }
    },
    totalCount: ({ state }) => {
      let totalCount = 0;
      const shareData = Object.values(state.share.data);
      for (let i = 0; i < shareData.length; i +=1) {
        totalCount += shareData[i].facebook;
        totalCount += shareData[i].twitter;
      }
      return totalCount;
    }
    ...
  }
}
```

That's it! Now when you use `state.share.totalCount` in React everything will be updated without having to do anything additional on your end.

You can also use derived state with additional custom parameters. Such a function works like a "getter" for a piece of state:

```javascript
state: {
  share: {
    data: {
      "/my-first-post": {
        "facebook": 15,
        "twitter": 12,
      },
      "/my-second-post": {
        "facebook": 43,
        "twitter": 64,
      }
    },
    totalCountByRoute: ({ state }) => route => {
      let totalCount = 0;
      totalCount += state.share.data[route].facebook;
      totalCount += state.share.data[route].twitter;
      return totalCount;
    }
    ...
  }
}
```

And then consumed like this: `state.share.totalCountByRoute("/my-first-post")`, so you should be able to create **derived state** for pretty much anything.

Additionally, Frontity gives you access to both `state` as well as \[`libraries`]\('./libraries) in your derived state:

```javascript
state: {
  share: {
    data: {
      "/my-first-post": {
        "facebook": 15,
        "twitter": 12,
      },
      ...
    },
    // `html2react.processors` comes from the @frontity/html2react package.
    processorsCount: ({ state, libraries }) => {
      return libraries.html2react.processors.length;
    };
  }
}
```

These **derived state functions** are stripped out from the initial state we send to the client but don't worry, they are reinstantiated later in the client by Frontity to ensure everything is back to normal :)

{% hint style="info" %}
If you still have any questions about State in Frontity, please check out the [**community forum**](https://community.frontity.org), which is packed full of answers and solutions to all sorts of Frontity questions. If you don't find what you're looking for, feel free to start a new post.
{% endhint %}


# 6. Actions

Actions are a set of functions that your package needs to work or expose for other packages. They can modify the state and don't return anything.

{% hint style="info" %}
Actions don't return data. Data is always accessed via the state. That's because Frontity is following the [Flux pattern](https://facebook.github.io/flux/) (like Redux).
{% endhint %}

Let's see one simple example:

```javascript
actions: {
    theme: {
        openMenu: ({ state }) => {
            state.theme.isMenuOpen = true;
        },
        closeMenu: ({ state }) => {
            state.theme.isMenuOpen = false;
        } 
    }
}
```

**Actions** are similar to **derived state**. They receive `({ state })` in their argument but that gets stripped out when you consume them:

```jsx
actions.theme.openMenu();
```

And similar to derived state functions, they can also receive arguments if they are declared using a second function:

```javascript
actions: {
    theme: {
        setMenu: ({ state }) => value => {
            if (value === "open")
                state.theme.isMenuOpen = true;
            else if (value === "closed")
                state.theme.isMenuOpen = false;
        },
    }
}
```

And they are consumed like this:

```jsx
actions.theme.setMenu("open");
```

Actions can be used either by their own package or by other packages.

For example, `tiny-router` (and all packages that want to implement the `router` API) exposes the action `actions.router.set()`. This action modifies `state.router.link` and makes sure that the URL of your browser is in sync. Additionally, `tiny-router` also runs this action if users click on the *back* and *forward* buttons of their browsers.

By the way, you can access the actions in the client console using:

```
> frontity.actions
```

## Frontity Lifecycle Initialization Actions

There are a set of special actions that Frontity runs at appropriate moments when [initializing the app](/isomorphic-react#initialization-of-a-frontity-app) in either the Client and the server-side :

![](https://frontity.org/wp-content/uploads/2021/06/Frontity-Lifecycle-Initialization-Actions.png)

### `init` (client & server)

Packages can use this action to initialize their internal libraries. Packages should not use actions or libraries from other packages as they may not be properly initialized.

### `beforeSSR` (server only)

The purpose of this action is to prepare the state for the React render made in the server. Packages can populate it with content fetched from external APIs, like the WP REST API. They can also interact with other packages if necessary.

You can *optionally* use the [curried](https://en.wikipedia.org/wiki/Currying) version of `beforeSSR` which is called with an object that contains the [Koa Context](https://koajs.com/#context) in the `ctx` parameter. You can use this `ctx` to modify things like status codes, headers and so on.

```javascript
// Without the context
{
  beforeSSR: ({ state, libraries }) => {
    console.log('Gonna SSR this page');
  }
}

// The optional curried version using the context
{
  beforeSSR: ({ state, libraries }) => async ({ ctx }) => {
    // ctx is koa context: https://koajs.com/#context
    console.log('SSR all day long', ctx.status);
  }
}
```

### `afterSSR` (server only)

This action runs after the HTML has been generated by React, but before the `state` snapshot is taken and the HTML is sent to the client. Therefore, packages can use the `afterSSR` step for things like setting headers or removing parts of the `state` that shouldn't be exposed to the client.

### `beforeCSR`  (client only)

This action is run before React is hydrated. Be aware that the state that React needs for the hydration is already received from the server so you don't need to replicate the fetching done in `beforeSSR`.

### `afterCSR`  (client only)

This action is run after React has been hydrated in the client and it has taken control of the page. This is where packages with client-side logic can start doing their thing.

{% hint style="info" %}
If you still have any questions about Actions in Frontity, please check out the [**community forum**](https://community.frontity.org), which is packed full of answers and solutions to all sorts of Frontity questions. If you don't find what you're looking for, feel free to start a new post.
{% endhint %}


# 7. Libraries

Do you remember [Actions](/learning-frontity/actions)? Libraries are pretty similar. Actions have been defined as a reusable set of functions aimed to change the state of the application. Similarly, **libraries** are a reusable set of tools. However, it is NOT aimed to change the state, but rather other parts of the application and is available for use by many packages.

Let's see two different examples: `stringify` and the array of processors of `html2react`.

## Stringify

In the `wp-source` package, we have a library called [`stringify`](https://docs.frontity.org/api-reference-1/wordpress-source#stringify-path-page-query-hash) which is used to create a route from the params you pass to it. This won't change the state, but it is reusable logic that has proven really useful.

```javascript
const path = "/category/nature";
const page = 4;

const nextPageLink = libraries.source.stringify({
    path,
    page: page + 1
});
// Outputs: "/category/nature/page/5"

const prevPageLink = libraries.source.stringify({
    path,
    page: page - 1
});
// Outputs: "/category/nature/page/3"
```

As you can see, we are creating two new URLs (one for next posts and other for previous ones) with the same code. This library accepts more params and you can perform more complex logic, but this is a good example of how to consume libraries and its reusability.

Like actions, libraries can be used either by their own packages or by other packages. For example, although `stringify` is defined inside `wp-source` package, it could also be use by your own theme.

## Array of processors from html2react

Another example is the array of processors from [html2react](/learning-frontity/libraries). There are some processors defined by default, but you can also add any processor you want, and it will be executed without additional code being needed.

For example, there is a processor for images where each time it finds an `<img>` tag, it transforms it to an `<Image />` component with some props and functionalities added to it.

You could add your own processor that finds every `<blockquote>` and transforms it into a new `<Blockquote />` component with your own logic.

{% code title="" %}

```jsx
import image from "@frontity/html2react/processors/image";
import blockquote from "./processors/blockquote";

const myTheme = {
  ...
  actions: {
    theme: {
      init: ({ libraries }) => {
        // We use html2react to process the <img> tags inside the content HTML.
        libraries.html2react.processors.push(image);
        libraries.html2react.processors.push(blockquote);
      }
    }
  }
  ...
};

export default myTheme;
```

{% endcode %}

That's basically all you need to know about libraries, a powerful way of reusing tools in Frontity. Oh, and you can access the available libraries in the client console using:

```
> frontity.libraries
```

{% hint style="info" %}
If you still have any questions about Libraries in Frontity, please check out the [**community forum**](https://community.frontity.org), which is packed full of answers and solutions to all sorts of Frontity questions. If you don't find what you're looking for, feel free to start a new post.
{% endhint %}


# 8. Namespaces

Now, let's talk about **namespaces** and how we, as a community, can use them to extend Frontity and create a better tool for everyone.

In **Frontity** `state`, `actions` and `libraries` belong to a shared space among all packages, so each package needs to use its own namespace.

To avoid conflicts between packages we could simply use the name of the package, but we use **namespaces** instead because some packages are interchangeable. For example, it doesn't matter if you install `wp-comments` (native WordPress comments) or `disqus-comments` (Disqus comments) in your Frontity project because the theme is going to access it using the common `comments` namespace and everything is going to work. In the future, another person could create a third `comments` package, based on a new service, and as long as it respects the same structure (written in TypeScript), all the themes (even the old ones!) will work perfectly.

More examples of **namespaces** are:

* `source`: for example `wp-source`, `wpgrahql-source` or even `drupal-source`…
* `analytics`: for example `google-analytics`, `gtm-analytics`, `mixpanel-analytics`…
* `notifications`: for example `onesignal-notifications`, `pushwoosh-notifications`…
* `share`: for example `modal-share`, `native-share`…
* `router`: for example `tiny-router`, `3d-router`…

But let's start from the beginning.

## Using namespaces in package exports

As we've already seen, this could be a typical `theme` package:

{% code title="/packages/my-awesome-theme/src/index.js" %}

```javascript
import Theme from "./components";

export default {
  roots: {
    theme: Theme,
  },
  state: {
    theme: {
      menu: [
        ["Home", "/"],
        ["About", "/about"],
      ],
      isMenuOpen: false,
      featuredImage: {
        showOnList: false,
        showOnPost: false,
      },
    },
  },
  actions: {
    theme: {
      toggleMenu: ({ state }) => {
        state.theme.isMenuOpen = !state.theme.isMenuOpen;
      },
    },
  },
};
```

{% endcode %}

One thing you might notice is that `roots`, `state`, and `actions` have a namespace called `theme`. It may seem like it is not adding much value because it is the only namespace. Why not write it like this instead?

{% code title="/packages/my-awesome-theme/src/index.js" %}

```javascript
import Theme from "./components";

export default {
  namespace: "theme",
  roots: Theme,
  state: {
    menu: [
      ["Home", "/"],
      ["About", "/about"],
    ],
    isMenuOpen: false,
    featuredImage: {
      showOnList: false,
      showOnPost: false,
    },
  },
  actions: {
    toggleMenu: ({ state }) => {
      state.theme.isMenuOpen = !state.theme.isMenuOpen;
    },
  },
};
```

{% endcode %}

There are several reasons:

### 1. It's easier to be aware of the final structure

When you access state or actions, it's much easier to see what you need when you write it like this:

{% code title="" %}

```javascript
state: {
  theme: {
    isMenuOpen: false,
  }
},
actions: {
  theme: {
    toggleMenu: ({ state }) => {
      state.theme.isMenuOpen = !state.theme.isMenuOpen; // <- Easy, right?
    }
  }
}
```

{% endcode %}

### 2. It's easier for TypeScript

Even though TypeScript is optional in **Frontity**, we make sure it has excellent support in case you want to use it. TypeScript gets really complex when you try to modify the structure of your objects, and in order to make it as simple as possible, it's good to create objects with the same structure that they will be consumed later. So yes, TypeScript just works :)

### 3. Multiple namespaces per package

Packages can export multiple namespaces and that's good. It makes **Frontity** more flexible.

For example, imagine we want to create a theme that implements its own share:

{% code title="/packages/my-awesome-theme-with-share/src/index.js" %}

```javascript
import Theme from "./components/theme";
import Share from "./components/share";

export default {
  roots: {
    theme: Theme,
    share: Share
  },
  state: {
    theme: {
      ... // State for the theme
    },
    share: {
      ... // State for the share
    }
  },
  actions: {
    theme: {
      ... // Actions for the theme
    },
    share: {
      ... // Actions for the share
    }
  }
}
```

{% endcode %}

## Making Frontity extensible through namespaces

This is the main reason namespaces exist in **Frontity** and a big part of how Frontity itself works.

We use namespaces to create abstractions on top of packages and, by doing so, they can communicate between each other without really knowing the specific implementation.

It's easier to understand with some examples.

### Example: `comments`

Take for example the [`@frontity/wp-comments`](https://api.frontity.org/frontity-packages/features-packages/wp-comments) package which has an [`actions.comments.submit`](https://api.frontity.org/frontity-packages/features-packages/wp-comments#actions-comments-submit) method. As you can see this method is defined under the `comments` namespace.

In the case of the `@frontity/wp-comments` package the `actions.comments.submit` is responsible for sending the content of the fields in the comment form to WordPress.

Now, all the `theme` packages that want to submit a comments form can check if there is a package with the `comments` namespace with an `actions.comments.submit` method available. If there is, it can be used from any React component in the project to submit comment form data.

```javascript
// Submit the comment to the post with ID 60
// using the values passed as the second argument.
actions.comments.submit(60, {
  content: "This is a comment example. Hi!",
  authorName: "Frontibotito",
  authorEmail: "frontibotito@frontity.com",
});
```

Users can use their `frontity.settings.js` to install and configure `wp-comments`:

{% code title="frontity.settings.js" %}

```javascript
export default {
  packages: [
    "my-awesome-theme",
    "@frontity/tiny-router",
    "@frontity/wp-source",
    "@frontity/wp-comments", // <- That's it. You have native wp comments now.
  ],
};
```

{% endcode %}

But what if (and now this is where things become interesting) users don't want to use WordPress native comments but [Disqus](https://disqus.com/) comments?

Then they just have to install a possible `disqus-comments` package instead:

{% code title="frontity.settings.js" %}

```javascript
export default {
  packages: [
    "my-awesome-theme",
    "@frontity/tiny-router",
    "@frontity/wp-source",
    "@frontity/disqus-comments", // <- That's it. You have disqus now.
  ],
};
```

{% endcode %}

This possible `disqus-comments` package might define a different implementation of `actions.comments.submit` that instead of submitting the comment form data to WordPress it would instead submit it to be handled by Disqus.

Actually, the `theme` has no idea about what specific implementation of `comments` you have installed. Everything works and the theme didn't need to change.

### Example: `analytics`

Let's take a look at another example: two actions in the `analytics` namespace. All the packages that want to implement analytics need to have these two actions:

* `actions.analytics.sendPageview`: send a pageview to the analytics service.
* `actions.analytics.sendEvent`: send an event to the analytics service.

The first one, `actions.analytics.sendPageview`, is used by packages that implement `router`, each time `actions.router.set` is used.

The second one, `actions.analytics.sendEvent`, is used by the theme when something interesting happens. For example:

{% code title="Post.js" %}

```jsx
const Post = ({ actions }) => (
  <Post>
    <Title />
    <Content />
    <ShareButtons onClick={actions.theme.openShareModal} />
  </Container>
);

export default connect(Post);
```

{% endcode %}

{% code title="/packages/theme/src/index.js" %}

```jsx
export default {
  state: {
    theme: {
      shareOpen: false,
    },
  },
  actions: {
    theme: {
      openShareModal: ({ state, actions }) => {
        state.theme.shareOpen = true;
        if (actions.analytics) {
          actions.analytics.sendEvent("share-modal-open");
        }
      },
    },
  },
};
```

{% endcode %}

When users open the share modal, a new event is sent to the analytics service of the `analytics` package that is installed in the **Frontity** project, no matter which one it is 🎉🎉

{% hint style="info" %}
If you still have any questions about Namespaces in Frontity, please check out the [**community forum**](https://community.frontity.org), which is packed full of answers and solutions to all sorts of Frontity questions. If you don't find what you're looking for, feel free to start a new post.
{% endhint %}


# 9. Styles

You should now know all the concepts needed to master **Frontity**, so let's see how you can customize your theme.

Frontity takes a different approach than WordPress when customizing themes. While in WordPress you have different `style.css` files and you add classes to your elements, **Frontity** uses **CSS in JS** instead. But don't worry, you don't have to learn a new language, it is CSS at the end.

CSS in JS, apart from having a better developer experience while working with React, has many other advantages like:

* **Only loads the CSS needed** for each page which improves the performance
* You **don't have to worry about classes** and its problems with duplication, typos, etc
* You **don't have to worry about vendor prefixing** so you can write your CSS based on the current standard and Frontity handles the rest for you
* You can use all the **power of JavaScript** to style your components and create dynamic styles with much less code

{% hint style="info" %}
In this video the DevRel team talks about CSS In JS in Frontity:

* 📺 [Frontity Talks 2020-01 - wp-source & CSS In JS \[26:49\]](https://www.youtube.com/watch?v=e-_66W8pfdY\&t=1609s)&#x20;
  {% endhint %}

Let's learn some of the CSS in JS concepts to be able to use it with Frontity:

## Styled

In order to style your app, you will usually create new React components from HTML tags (or even other React components) with new styles attached to them. To do so, we will import `styled` from `frontity`, and create styled-components.

When styling HTML tags, you just use `styled` followed by the HTML tag, and then a template string with the CSS, like this:

```jsx
import { styled } from "frontity";

const StyledDiv = styled.div`
    width: 100%;
    text-align: center;
    color: white;
`;
```

If you want to style another React component, you use `styled` like a function. The `styled` method works perfectly on all of your own or any third-party component, as long as they attach the passed `className` prop to a DOM element.

```jsx
import { styled } from "frontity";

const Link = ({ className, href, children }) => (
    <a href={href} className={className}>
        {children}
    </a>
);

const StyledDiv = styled(Link)`
    width: 100%;
    text-align: center;
    color: white;
`;
```

Then, you use those styled-components in React.

```jsx
import { styled } from "frontity";
import Link from "./link";

const Component = () => (
    <StyledDiv> // This StyledDiv is defined later.
        <GreenLink> // This GreenLink is defined later.
            Click Me!
        </GreenLink>
    </StyledDiv>
);

// We create a variable to use later as example.
const linkColor = "green";

// We create a new component, that is a div with these styles.
const StyledDiv = styled.div`
    width: 100%;
    text-align: center;
    color: white;
`;

// We create a new component from Link and use a variable.
const GreenLink = styled(Link)`
    background-color: ${linkColor};
`;
```

As you can see, it is really easy to work with, and you are still using common CSS. There are some important things to note:

* You can create styled-components from HTML tags or React components, although the syntax is slightly different
* You can use JavaScript inside the template strings

  In this case we are using a variable `linkColor` but you can do anything you want

## The `CSS` prop

Sometimes, you won't need to create a new component, and you will just want to add some CSS to an element. This is similar to inline styles, and you can do this by importing `css` from `frontity` .

```jsx
import { css } from "frontity";

const Component = () => (
    <div css={css`background: pink`}>
        Styling my theme
    </div>
);
```

This way, we will be styling just that div.

## Dynamic CSS using props

You can pass a function to a styled component's template string to adapt it based on its props. This `button` component has a `color` prop that changes, well, its color.

```jsx
const Button = styled.button`
  color: ${props => props.color || "red"};
`;

const Component = () => (
  <>
    <Button>This is red</Button>
    <Button color="palevioletred">This is palevioletred</Button>
  </>
);
```

## React's `style` prop

{% hint style="warning" %}
React has its own way of adding inline style, using the `style` prop, but **you should not use it** because the CSS you write there won't be optimized by Frontity!
{% endhint %}

**You should not use `style`!**

```jsx
const Page = () => (
  <div style={{
      margin: '40px',
      border: '5px solid pink'
  }}>
    This style cannot be optimized by Frontity! :(
  </div>
);
```

Instead, use the **CSS prop** or create a **styled component**:

```jsx
const Page = () => (
    <div css={css`
        margin: 40px;
        border: 5px solid pink;
    `}>
        This style can be optimized by Frontity! :)
    </div>
);
```

```jsx
const Page = () => (
    <StyledDiv>
        This style can be optimized by Frontity! :)
    </StyledDiv>
);

const StyledDiv = styled.div`
    margin: 40px;
    border: 5px solid pink;
`;
```

## `<Global>`

There will be times when you want to add styles for the whole app. For example defining styles for the `h1` , `h2` or `body` tags. In Frontity, this can be done with the `Global` component.

```jsx
import { Global, css } from "frontity";

const Page = () => (
    <>
        <Global
          styles={css`
            body {
                margin: 0;
                font-family: "Roboto";
            }
          `}
        />
        <OtherContent />
    </>
);
```

You will usually add this in the `index.js` of your theme, so you can make sure it loads on all your pages.

Frontity will include the CSS defined inside a `<Global>` component only if it is present in the DOM. You can use that ability to add conditional CSS, like this:

```jsx
const Background = ({ state }) =>
  state.theme.darkTheme ? (
    <Global styles={css`
      body { background-color: black; }
    `} />
  ) : null;
```

{% hint style="warning" %}
**Using `<Global>` for anything other than HTML tags is not recommended** because Frontity is not able to optimize it. That means you can use it for tags like `html`, `body` , `a`, `img`, and so on... But **avoid it for classes**. Use either the CSS prop or styled-components instead.
{% endhint %}

**You should not use `<Global>` for classes!**

```jsx
const Component = () => (
    <>
        <Global styles={css`
            .my-class {
                margin: 40px;
                border: 5px solid pink;
            }
          `}
        />
        <div className="my-class">
            This style cannot be optimized by Frontity! :(
        </div>
    </>
);
```

Instead, use the **CSS prop** or create a **styled component**:

```jsx
const Page = () => (
    <div css={css`
        margin: 40px;
        border: 5px solid pink;
    `}>
        This style can be optimized by Frontity! :)
    </div>
);
```

```jsx
const Page = () => (
    <StyledDiv>
        This style can be optimized by Frontity! :)
    </StyledDiv>
);

const StyledDiv = styled.div`
    margin: 40px;
    border: 5px solid pink;
`;
```

## External CSS files

External CSS files should be imported using the `<Global>` component.

{% hint style="info" %}
When you import a CSS file in Frontity, it is just a string of CSS.
{% endhint %}

Add the `<Global>` component with the external styles to your theme:

```jsx
import { Global, css } from "frontity";
import externalCss from "some-library/styles.css";

const Theme = ({ state }) => {
  ...

  return (
    <>
      <Head>
        ...
      </Head>
      <Body>
        ...
      </Body>

      <Global styles={css(externalCss)} />
    </>
  );
};
```

{% hint style="warning" %}
**Using `<Global>` for anything other than HTML tags is not recommended** because Frontity is not able to optimize it. That means you can use it to import external styles, but if you really want Frontity to be able to optimize it, you should extract that CSS and move it to styled-components instead.
{% endhint %}

## Keyframes

Finally, the last import you may need is `keyframes`. This one is used to define and use animations in your CSS.

```jsx
import { styled, keyframes } from "frontity";

// Create the keyframes.
const rotate = keyframes`
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
`;

// Add the animation to Button.
const Button = styled.button`
  background-color: hotpink;
  animation: ${rotate} 2s linear infinite;
`;

const Component = () => (
  <Button>Styling my theme</Button>
);
```

And that's all you need to style your theme!

## Emotion Documentation

For managing the styles shown above, Frontity has integrated and configured [Emotion](https://emotion.sh/docs/styled).

If you want to go deeper, you should take a look at their docs. You don't need to read the docs on how to install and configure Emotion, we have already done that work for you. The items below are particularly useful to learn more about:

* [Styled-components](https://emotion.sh/docs/styled)
* [Composition](https://emotion.sh/docs/composition)
* [Nested Selectors](https://emotion.sh/docs/nested)
* [Media Queries](https://emotion.sh/docs/media-queries)
* [Global Styles](https://emotion.sh/docs/globals)
* [Keyframes](https://emotion.sh/docs/keyframes)

That's it! You are now a master of CSS in JS.

## From Sass to CSS in JS

### Why can I not use SASS?

Frontity is an "opinionated framework" because it comes with its own State Manager and CSS solution.

That's not common among the JS framework space, but it gives Frontity some advantages we deem crucial for its success: all the Frontity packages use the same system for state managing and styling. That means things like:

* They are able to communicate between each other&#x20;
* They all use the same modules so the bundle size is not increased when you add a new package
* We can offer out-of-the-box optimizations other frameworks can't

For a more in-depth explanation about the reasons we believe it's a good approach to stick to CSS in JS vs other CSS solutions, please take a look at this [community thread](https://community.frontity.org/t/use-css-or-scss-instead-of-emotion/451/9?u=luisherranz).

### Sass to CSS in JS resources

CSS in JS supports all the Sass features. If you are used to SASS, our recommendation is to learn CSS in JS. It won't take you more than 30 minutes to learn how to do the very same things you are used to doing in Sass.

These are some resource you might find useful to make the transition to CSS in JS:

{% embed url="<https://medium.com/styled-components/getting-sassy-with-sass-styled-theme-9a375cfb78e8>" %}

{% embed url="<https://egghead.io/courses/convert-scss-sass-to-css-in-js>" %}

{% embed url="<https://jsramblings.com/2017/10/29/migrating-to-styled-components-cheatsheet.HTML>" %}

### Migrating from Sass to CSS in JS

If you already have a base of Sass you want to migrate, you can use these tools to extract your variables and use them directly in JavaScript:

* <https://github.com/adamgruber/sass-extract-js>
* <https://github.com/jgranstrom/sass-extract>

{% hint style="info" %}
If you still have any questions about Styles in Frontity, please check out the [**community forum**](https://community.frontity.org), which is packed full of answers and solutions to all sorts of Frontity questions. If you don't find what you're looking for, feel free to start a new post.
{% endhint %}


# Architecture

In Frontity projects, WordPress is used as a [headless CMS](https://css-tricks.com/what-is-a-headless-cms/). Frontity uses data from the WP REST-API and generates the final HTML that is displayed in the browser using React. This means that WordPress is merely used for managing the content.

A Frontity project will always require two servers:

1. A **WordPress Server (PHP)**, either:
   * An Apache or Nginx web server running PHP
   * A hosted software-as-a-service (SaaS) platform with WordPress such as WordPress.com
2. A **Frontity Server (Node.js)**, either:
   * A server running Node.js
   * A hosted function-as-a-service (FaaS) platform allowing serverless computing, such as AWS Lambda or Netlify functions

There are then two main [**Frontity Modes**](https://excalidraw.com/#json=5295841782792192,H5-J_CUaq_wM0KYYacHysg) (architectures or configurations) that can be used to implement Frontity projects:

* [**Decoupled mode**](/architecture/decoupled-mode)
* [**Embedded mode**](/architecture/embedded-mode)

Depending on the mode used, the **main domain** (e.g. `www.domain.com`) will be connected either to the Wordpress/PHP Server *(in Embedded mode)* or to the Frontity/Node.js server *(in Decoupled mode)*. The main domain is the one used by site visitors to access the HTML of the site.

The other server will get a secondary role and its domain can be either a **separate domain** (e.g. `project-d418mhwf5.vercel.app`) or a **sub-domain** of the main domain (e.g. `wp.domain.com`).

Both of the two possible Frontity architectures (i.e. Decoupled or Embedded Mode) feature:

* A *similar distribution of functionality across the servers*
  * WordPress is used as a CMS - to manage the content
  * Frontity is responsible for the presentation
* A *similar operation*
  * Frontity fetches the data from the WordPress REST API
  * Frontity generates the final HTML as an [Isomorphic](/isomorphic-react) React App

Both of these architectures (or modes) require *two different servers* with *two different URLs* but the communication workflow between these two servers differs in each case.

| Decoupled Mode                                                                                                                                                  | Embedded Mode                                                                                                                                                 |
| --------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [![](https://frontity.org/wp-content/uploads/2021/05/workflow-decoupled-mode.png)](https://frontity.org/wp-content/uploads/2021/05/workflow-decoupled-mode.png) | [![](https://frontity.org/wp-content/uploads/2021/05/workflow-embedded-mode.png)](https://frontity.org/wp-content/uploads/2021/05/workflow-embedded-mode.png) |

{% hint style="info" %}
Implementing a [**caching strategy**](/performance/caching) in Frontity projects is highly recommended to improve response times. A [WordPress Cache plugin](https://wordpress.org/plugins/simple-cache/) is especially recommended to cache REST API requests in both architectures.
{% endhint %}

## Decoupled Mode

![](https://frontity.org/wp-content/uploads/2021/05/decoupled-mode-simple-diagram.png)

[**Decoupled mode**](/architecture/decoupled-mode) is implemented as follows:

* It uses two domains, one for WordPress and another for Frontity.
* The main domain ([www.domain.com](http://www.domain.com/)) points to Frontity.
* A secondary domain (which can be a subdomain such as [wp.domain.com](http://wp.domain.com/)) points to WordPress.

In this mode site visitors access the site using the main domain and are served HTML pages directly from Frontity, and the secondary domain is used by content editors to access the WordPress admin pages. Frontity fetches data from the REST API located on the secondary domain, i.e. the WordPress installation.

{% hint style="info" %}
Decoupled mode needs no additional structural elements, such as plugins.
{% endhint %}

## Embedded Mode

![](https://frontity.org/wp-content/uploads/2021/05/embedded-mode-simple-diagram.png)

[**Embedded Mode**](/architecture/embedded-mode) is implemented as follows:

* The main domain ([www.domain.com](http://www.domain.com/)) points to WordPress.
* The secondary domain (which can be a subdomain of the main domain) points to Frontity.
* All the requests are handled by WordPress. No reverse proxy is needed.
* The PHP theme is replaced with an internal HTTP request to the Frontity server.
* Other WordPress URLs (i.e. those not handled by Frontity) work normally.

In *Embedded mode* the main domain points to the WordPress installation, and the secondary domain points to the node.js server running Frontity. In this mode both site visitors and content editors use the same domain, i.e. the main domain, to either visit the site or access the admin pages. The secondary domain is never directly accessed.

{% hint style="info" %}
Embedded mode requires the [Frontity Embedded Mode plugin](https://api.frontity.org/frontity-plugins/embedded-mode). This plugin replaces the WordPress theme with its own template file which fetches the HTML from the Frontity server.
{% endhint %}

Since, in embedded mode, the Frontity site is never directly accessed the secondary domain can be anything - including free domains allocated by the node.js hosting service.


# Decoupled Mode

In **Decoupled mode** the *primary domain points to the Node.js server hosting Frontity*. This is the site that visitors access directly in order to view the content.

Frontity will fetch the data from the REST API of the WordPress Server and will return the final HTML as an [Isomorphic](https://medium.com/capital-one-tech/why-everyone-is-talking-about-isomorphic-universal-javascript-and-why-it-matters-38c07c87905) React App.

![](https://frontity.org/wp-content/uploads/2021/04/frontity-architecture.png)

Any Frontity architecture requires two servers. In Decoupled Mode you need to have:

* A **main domain** pointing to the **Frontity Server**, either:
  * A server running Node.js
  * A hosted function-as-a-service (FaaS) platform allowing serverless computing, such as AWS Lambda or Netlify functions
* A **secondary URL** (or subdomain) pointing to the **WordPress Server**, either:
  * An Apache or Nginx web server running PHP
  * A hosted software-as-a-service (SaaS) platform with WordPress, such as WordPress.com

In this mode site visitors access the site using the primary domain and are served HTML pages directly from Frontity. The secondary domain is used by content editors to access the WordPress admin pages.

Frontity fetches data from the REST API located on the secondary domain, i.e. the WordPress installation, and uses that information to generate the HTML that is returned to the user.

![](https://frontity.org/wp-content/uploads/2021/05/workflow-decoupled-mode.png)

{% hint style="info" %}
The `state.source.url` property set in the `frontity.settings.js` file [configures the URL of the WordPress installation](/guides/setting-url-wordpress-source-data).
{% endhint %}

## Table of Contents

* [Features of the Decoupled Mode](/architecture/decoupled-mode#features-of-the-decoupled-mode)
  * [Technical considerations](/architecture/decoupled-mode#technical-considerations)
* [Caching in Decoupled Mode](/architecture/decoupled-mode#caching-in-decoupled-mode)

## Features of the Decoupled Mode

The Decoupled Mode offers a number of **advantages**:

* **No extra WordPress plugin** is required for this mode
* It has the **fastest workflow to respond to the requests**: just a single call in SSR is made to the WP REST API, with no round-robin request for content and return of HTML.
* It **provides an extra layer of security** as the WordPress site is not on the public-facing domain.

Decoupled Mode uses two different domains. The main one ([www.domain.com](http://www.domain.com/)) for Frontity and a subdomain ([wp.domain.com](http://wp.domain.com/)) for WordPress.

### Technical considerations

Due to the two-domains nature of this mode, in *Decoupled Mode* e developers need to be aware of, test, and take care of many things that are normally handled for you by WordPress. For example:

* *URL replacements* from [wp.domain.com](http://wp.domain.com/) to [www.domain.com](http://www.domain.com/). *(see the ☝️ hint below)*
* *Cross-domain 301 redirections* from Frontity to WordPress and vice-versa.
* *301 redirections* of individual URLs stored in the WordPress database.
* *Proxying WordPress resources* that need to be served from the [www.domain.com](http://www.domain.com/) domain.
* Adding *CORS headers* in the [wp.domain.com](http://wp.domain.com/) domain.
* *Purging page cache* of the [www.domain.com](http://www.domain.com/) domain.

{% hint style="info" %}
☝️ In the guide [URLs in a Migration from WordPress to Frontity Decoupled Mode](/guides/update-db-urls) you can learn more about why you need to change these URLs in the content of your WordPress site. The guide also provides useful information on how to do so.
{% endhint %}

Additionally, in Decoupled Mode it is impossible to replicate the editing experience that content editors may be used to because in this mode it’s not possible to:

* Render the *admin bar* for logged in users.
* Make 100% transparent *post previews*.

![](https://frontity.org/wp-content/uploads/2021/05/decoupled-mode-features.png)

## Caching in Decoupled Mode

With a good [**caching strategy**](/performance/caching) your Frontity project can be just as performant as a static site.

In *Decoupled Mode*, the main domain is connected to the Node.js server executing the Frontity app which will process the URL requests to return the proper HTML based on the data from the WP REST API.

In this mode there are two types of requests that can be cached to minimize the computing time and to take advantage of the proximity of CDN servers:

* [CDN for caching URL requests made to Frontity](/performance/caching#cdn-for-frontity-servers)
* [Server caching for REST API requests in WordPress servers](/performance/caching#server-caching-for-rest-api-requests-in-wordpress-servers)

![](https://frontity.org/wp-content/uploads/2021/05/cache-decoupled-mode.png)


# Embedded Mode

In **Embedded Mode** the *primary domain points to the WordPress server*. This is the URL that visitors access directly in order to view the content.

WordPress (via the [Frontity Embedded Mode plugin ](https://api.frontity.org/frontity-plugins/embedded-mode)) will redirect the request to Frontity, which will get the data from the REST API to return the final HTML as an [Isomorphic](https://medium.com/capital-one-tech/why-everyone-is-talking-about-isomorphic-universal-javascript-and-why-it-matters-38c07c87905) React App that will be returned to the user by WordPress.

![](https://frontity.org/wp-content/uploads/2021/05/frontity-embedded-mode.png)

Any [Frontity architecture requires 2 servers](/architecture). In Embedded Mode you need to have:

* A **main domain** pointing to the **WordPress Server**, either:
  * An Apache or Nginx web server running PHP
  * A hosted software-as-a-service (SaaS) platform with WordPress such as WordPress.com (only plans allowing plugin installation)
* A **secondary URL** (or subdomain) pointing to the **Frontity Server**, either:
  * A server running Node.js
  * A hosted function-as-a-service (FaaS) platform allowing serverless computing such as AWS Lambda or Netlify functions

In this mode *both site visitors and content editors use the same domain*, i.e. the main domain, to either visit the site or access the WordPress admin pages. The Frontity server on the secondary domain is never directly accessed.

{% hint style="warning" %}
This mode requires the installation, activation and configuration of the [**Frontity embedded mode plugin**](https://api.frontity.org/frontity-plugins/embedded-mode) to work.
{% endhint %}

The [Frontity Embedded Mode plugin](https://api.frontity.org/frontity-plugins/embedded-mode) required by this mode, replaces the WordPress theme with its own template file which fetches the HTML from the Frontity server. However, before Frontity can deliver the HTML it must request the content from the WordPress REST API, necessitating a two stage round trip.

![](https://frontity.org/wp-content/uploads/2021/05/workflow-embedded-mode.png)

{% hint style="info" %}
Due to the "two stage round trip", [**caching**](/architecture/embedded-mode#caching-in-embedded-mode) **is therefore a necessity** in this architecture to ensure that site performance is optimal.
{% endhint %}

## Table of Contents

* [Features of the Embedded Mode](/architecture/embedded-mode#features-of-the-embedded-mode)
  * [Technical considerations](/architecture/embedded-mode#technical-considerations)
* [Caching in Embedded Mode](/architecture/embedded-mode#caching-in-embedded-mode)

## Features of the Embedded Mode

Embedded Mode offers several **advantages** over Decoupled Mode.

* The WordPress site exists under the primary domain, thus ensuring that:
  * all the ***SEO benefits*** already built-in to WordPress work as normal
  * *existing SEO* (for a site transitioning to Frontity) will not be affected
  * ***sitemaps*** generated by WordPress/Yoast/All-in-one-SEO work as normal
  * ***WordPress page cache plugins and hosting CDNs*** continue to work as normal
* Content producers/editors continue to have the same experience
  * ***post/page preview*** remains available
  * the ***admin bar*** is active for logged in users

In addition, since the Frontity site is never directly accessed the secondary domain can be anything - including free domains allocated by the node.js hosting service - so there is no need to purchase an additional domain or configure DNS settings for sub-domains.

{% hint style="info" %}
In this mode, a [serverless](https://about.gitlab.com/topics/serverless/) solution to host the Frontity server is especially recommended as it will make it cheap, easy and infinitely scalable.
{% endhint %}

But there are some *things that should be taken into account* when using Embedded Mode:

* It requires an additional plugin, namely the [Frontity embedded mode plugin](https://api.frontity.org/frontity-plugins/embedded-mode).
* It will not work with free wordpress.com plans as the installation of a plugin is required.
* WordPress still needs to go through it's [bootstrap process](https://wordpress.tv/2017/06/22/alain-schlesser-demystifying-the-wordpress-bootstrap-process/) on initial page load
* More routing is involved (resulting in potentially slower execution than Decoupled Mode) with the "two stage round trip" (WordPress → Frontity → WP REST API → Frontity → WordPress), so **a caching strategy is a necessity** rather than simply a nice to have.

### Technical considerations

Due to the one-domain nature of this mode and the fact that the routing is managed by WordPress, *developers don’t need to take care of any of the issues mentioned on the* [*Decoupled Mode*](/architecture/decoupled-mode#technical-considerations) page, including:

* URL replacements
* Cross-domain 301 redirections
* CORS headers
* Purge page cache
* Proxy WordPress resources from the Frontity server
* WordPress posts 301 redirections
* Maintain the reverse proxy configuration

These are all either unnecessary (in the case of URL replacements), or continue to be handled by WordPress.

In this mode content editors continue to have the same editing experience:

* The admin bar is visible for logged in users.
* Post previews work just the same as in a normal (non-headless) WordPress installation.

{% hint style="warning" %}
In order to access post previews from the REST API revisions need to be activated. You can read more about revisions on the [official WordPress docs](https://wordpress.org/support/article/revisions/). And if you are using custom post types, remember to [add support for revisions](https://developer.wordpress.org/reference/functions/register_post_type/#supports) when you register them.
{% endhint %}

## Caching in Embedded Mode

In **Embedded Mode** the main domain is connected to the WordPress server which will use a custom template (provided by the plugin) to redirect to the Frontity Web Server in order to get the proper HTML based on the data of the WP REST API.

![](https://frontity.org/wp-content/uploads/2021/05/embedded-mode-features-cache.png)

In this model the following cache layers are **highly recommended**:

* [CDN for caching URL requests made to WordPress](/performance/caching#cdn-for-wordpress-servers)
* [Server caching for URL requests in WordPress servers](/performance/caching#server-caching-for-url-requests-in-wordpress-servers)
* [Server caching for REST API requests in WordPress servers](/performance/caching#server-caching-for-rest-api-requests-in-wordpress-servers)

{% hint style="warning" %}
As there is more routing involved in Embedded Mode (WordPress makes a call to Frontity, which makes a request to the WP REST API, which then returns the JSON to Frontity, and which then returns the HTML to WordPress) a **caching plugin for the HTML (caching the URL requests) is a necessity** rather than simply a nice to have.
{% endhint %}

![](https://frontity.org/wp-content/uploads/2021/05/cache-embedded-mode.png)


# Deployment

Once you have your application working and ready to be deployed you can create a production version by running (from the root of your project)

```
npx frontity build
```

This command will [generate a `build` folder](https://api.frontity.org/frontity-cli/build-commands#the-build-process) containing both your (isomorphic) React app and your Frontity (Node.js) server. This folder can be deployed to any hosting that is prepared to serve a Node.js app. The content of this `build` folder will be used by the command:

```
npx frontity serve
```

Which is used to launch the Frontity app in production.

Here you have some guides about how to deploy a Frontity app in some popular hostings:

* [Deploy Frontity using Vercel](/deployment/deploy-using-vercel)
* [Deploy Frontity on Layer0](/deployment/deploy-on-layer0)
* [Deploy Frontity on Heroku](/deployment/deploy-on-heroku)

## Serving Static files

Sometimes you will want to serve your assets (also called "static files" like images, fonts, JS chunk files) from another domain or from a [CDN](/performance/caching#distributed-caching-cdn). In this case, you can modify the [`publicPath` parameter](/deployment) when you run `npx frontity build`.


# Deploy Frontity using Vercel

In [their own words](https://vercel.com/docs) : *Vercel is a cloud platform for static sites and **Serverless Functions** that fits perfectly with your workflow. It enables developers to host Jamstack sites and web services that **deploy instantly**, **scale automatically**, and **requires no supervision**, all with **no configuration**.*

We strongly recommend this service as it is serverless, cheap, [includes CDN](/performance/caching#cdn-for-frontity-servers), and really easy to set up.

It also supports the cache technique stale-while-revalidate (which they call [Serverless Pre-Rendering](https://vercel.com/blog/serverless-pre-rendering)). This is a powerful way to improve your site speed.

## Table of Contents

* [Signup and Login into Vercel](/deployment/deploy-using-vercel#signup-and-login-into-vercel)
* [Deploy your site under a Vercel domain](/deployment/deploy-using-vercel#deploy-your-site-under-a-vercel-domain)
  * [Create a `vercel.json` file](/deployment/deploy-using-vercel#create-a-vercel-json-file)
  * [Run deployment](/deployment/deploy-using-vercel#run-deployment)
* [Deploy your site under a custom domain](/deployment/deploy-using-vercel#deploy-your-site-under-a-custom-domain)
  * [Add your custom domain from your Vercel project settings](/deployment/deploy-using-vercel#add-your-custom-domain-to-your-vercel-project-settings)
    * [Add a subdomain for your WordPress source](/deployment/deploy-using-vercel#add-a-subdomain-for-your-wordpress-source)
  * [Add Vercel nameservers in your domain provider](/deployment/deploy-using-vercel#add-vercel-nameservers-in-your-domain-provider)
  * [Deploy](/deployment/deploy-using-vercel#deploy)
* [Vercel and HTTPS](/deployment/deploy-using-vercel#vercel-and-https)

## Signup and Login into Vercel

To be able to deploy with `vercel` you need to have a Vercel account. You can [signup here](https://vercel.com/signup).

Once you have an account you have to [login](https://vercel.com/docs/cli#commands/login) to Vercel from the terminal.

```
> npx vercel login
```

## Deploy your site under a Vercel domain

Deploying to Vercel is really easy and all the required configuration for Frontity projects is automatically set for you via a `vercel.json` file.

So, to deploy your Frontity site under a Vercel domain you have to:

1. [Signup and Login](/deployment/deploy-using-vercel#signup-and-login-into-vercel) (if you haven't already).
2. [Create a `vercel.json` file](/deployment/deploy-using-vercel#create-a-vercel-json-file).
3. [Run deployment](/deployment/deploy-using-vercel#run-deployment).

### Create a `vercel.json` file

Create this [`vercel.json`](https://vercel.com/docs/configuration#introduction/configuration-reference) file and save it in the root of your Frontity project.

```
{
  "version": 2,
  "builds": [
    {
      "src": "package.json",
      "use": "@frontity/now"
    }
  ]
}
```

{% hint style="info" %}
[`@frontity/now`](https://github.com/frontity/now-builder) is a Frontity builder created especifically for Vercel. It encapsulates all the actions that need to be triggered on Vercel servers when deploying a Frontity project
{% endhint %}

### Run deployment

Deploy Frontity using the [`vercel` command](https://vercel.com/docs/cli#getting-started) (from the root of your project):

```
> npx vercel
```

You should get something like this

```
Vercel CLI 19.2.0
? Set up and deploy “~/PROJECTS/2020/FRONTITY/DEMOS/my-frontity-project”? [Y/n] y
? Which scope do you want to deploy to? myVercelScope
? Link to existing project? [y/N] n
? What’s your project’s name? my-frontity-project
? In which directory is your code located? ./
🔗  Linked to vercel-username/head-tags (created .vercel)
🔍  Inspect: https://vercel.com/vercel-username/my-frontity-project/lofg8n03c [2s]
✅  Production: https://my-frontity-project.vercel.app [copied to clipboard] [1m]
```

> More about Vercel [scopes ](https://vercel.com/docs/v2/platform/users-and-teams)

Vercel will assign you a domain (something like *your-project-name.vercel.app*) that that will allow you to check your site online.

From the above deployment example we got the following URL's:

* **Live URL:** `https://my-frontity-project.vercel.app` → Our temporary URL assigned automatically by Vercel, We can check (and share) our site online from this URL
* **Inspect:** `https://vercel.com/vercel-username/my-frontity-project/settings` → Here we can check the status of our site and check the logs among other things
* **Project Settings:** `https://vercel.com/vercel-username/my-frontity-project/settings` → Here we can change domain and build settings among other things

## Deploy your site under a custom domain

To deploy your site in Vercel under a custom domain you have to:

1. [Deploy your site under a Vercel domain](/deployment/deploy-using-vercel#deploy-your-site-under-a-vercel-domain) (if you haven't already).
2. [Add your custom domain to your Vercel project settings](/deployment/deploy-using-vercel#add-your-custom-domain-to-your-vercel-project-settings).
3. [Add Vercel nameservers for your custom domain from your domain provider](/deployment/deploy-using-vercel#add-vercel-nameservers-in-your-domain-provider)
4. [Run deployment](/deployment/deploy-using-vercel#deploy).

### Add your custom domain to your Vercel project settings

By visiting the project settings URL provided in our previous deployment (`https://vercel.com/vercel-username/my-frontity-project/settings` in our example above) we can set a custom domain.

![](https://frontity.org/wp-content/uploads/2021/04//now-projects-settings.png)

Add it, and you will be provided with a [set of nameservers](https://vercel.com/docs/v2/custom-domains#step-4:-configuring-the-domain) that you can use in your domain provider's configuration to point your custom domain to the Vercel nameservers.

![vercel nameservers](https://frontity.org/wp-content/uploads/2021/04//vercel-nameservers.png)

#### Add a subdomain for your WordPress source

A subdomain can be used to separate your WordPress and Frontity deployments. They can be created within the Vercel dashboard under the [domains section](https://vercel.com/dashboard/domains/).

To setup a subdomain for your WordPress source, simply select your desired domain from the [list](https://vercel.com/dashboard/domains/) and [add a new DNS Record](https://vercel.com/docs/v2/custom-domains#step-2:-add-dns-record) with type A and the IP address of your WordPress server.

### Add Vercel nameservers in your domain provider

You need to set [Vercel nameservers](https://vercel.com/docs/v2/custom-domains/#option-2:-using-external-nameservers) as custom DNS of your custom domain from your domain provider site.

{% hint style="info" %}
If you don't know how to do this, contact your domain provider (GoDaddy, CloudFlare, etc)
{% endhint %}

### Deploy

Finally, deploy Frontity using this command (from the root of your project):

```
> npx vercel --prod
```

You should get something like this

```
⬢  my-frontity-project  npx vercel --prod

🔍  Inspect: https://vercel.com/vercel-username/my-frontity-project/9ue4zsq9n [2s]
✅  Production: https://mycustomtomain.com [copied to clipboard] [4s]
```

This will create a deployment and assign it to your real site URL.

> More about Vercel [deployments](https://vercel.com/docs/v2/platform/deployments)

## Vercel and HTTPS

Vercel now forces all apps to be served over HTTPS. You therefore need to ensure that your WordPress site has a SSL certificate and that you connect to your WordPress API endpoint using HTTPS rather than HTTP.

```
{
      "name": "@frontity/wp-source",
      "state": {
        "source": {
          "url": "https://your-wordpress-blog-url/",
        }
      }
    },
...
```

The effect of using a HTTP only connection on a Frontity project deployed on Vercel will result in navigation links not working and getting stuck in the `data.isFetching` state (although apparently working on the local dev machine). The reason is that Frontity won't be able to fetch the content from the WordPress backend over HTTP on a pure HTTPS site.

{% hint style="info" %}
Still have questions? Ask [the community](https://community.frontity.org/)! We are here to help 😊
{% endhint %}


# Deploy Frontity on Layer0

[Layer0](https://layer0.co) is an all-in-one platform to develop, deploy, preview, experiment on, monitor, and run your headless frontend. It is focused on large, dynamic sites and best-in-class performance through EdgeJS (a JavaScript-based Content Delivery Network), predictive prefetching, and performance monitoring.

Layer0's EdgeJS enables powerful and precise control of Edge based [caching](https://docs.layer0.co/guides/caching) and [routing](https://docs.layer0.co/guides/routing) that can improve the performance for Frontity sites.

For the full details on deploying Frontity on Layer0 refer to the [Frontity on Layer0 guide](https://docs.layer0.co/guides/frontity) in the developer documentation.

## Getting Started

First start by installing the [Layer0 command-line interface (CLI)](https://docs.layer0.co/guides/cli),

```bash
npm i -g @layer0/cli
```

## Project setup

Run the `init` command in the directory of your Frontity project:

```bash
cd my-frontity-app
layer0 init
```

This will automatically configure your app for deployment on Layer0.

## Running locally

You can simulate your app running on Layer0 using the `dev` command:

```bash
layer0 dev
```

In particular, the `--cache` option will emulate Edge caching rules locally so that you can test easily test edge behavior during development without having to do a deploy to the cloud:

```bash
layer0 dev --cache
```

## Deploying

Deploying a Frontity app requires an account on Layer0. [Sign up here for free](https://app.layer0.co/signup).

Once you have installed the CLI and created an account, you should login from the terminal by running the `login` command:

```bash
layer0 login
```

Once you have an account and have logged in to the CLI, you can deploy to the Layer0 by running the following in the root folder of your project:

```
layer0 deploy
```

## Enabling Prefetching (optional)

Layer0 improves the performance of your site by bundling an integrated server worker that will predictively prefetch cached pages from the edge. To add the Layer0 service worker to your app, call the `install` function from `@layer0/prefetch/window` in a `useEffect` hook when the app first loads. For example, you can alter the Header component in your theme as follows:

```javascript
// mars-theme/src/components/header.js

import { useEffect } from 'react'

const Header = ({ state }) => {
  useEffect(() => {
    if (process.env.NODE_ENV === 'production') {
      install()
    }
  }, [])

  /* ... */
}
```

To prefetch data into the browser cache using the service worker, use the Prefetch component from @layer0/react. This component prefetches a specific URL from the Layer0 edge when it becomes visible in the viewport. You typically wrap it around links. For example:

```javascript
import { Prefetch } from '@layer0/react'

function MyComponent() {
  return (
    <Prefetch url="/some/data/url.json">
      {/* When this link is scrolled into view, /some/data/url.json in JSON will be fetched in the background and put in the browser cache */}
      <a href="/link/to/page">My Page</a>
    </Prefetch>
  )
}
```


# Deploy Frontity on Heroku

To be able to deploy to Heroku you need to have a Heroku account. You can [signup here](https://signup.heroku.com/).

You will also need to install the [Heroku CLI](https://devcenter.heroku.com/articles/getting-started-with-nodejs#set-up)

> The Heroku CLI requires Git, the popular version control system. If you don’t already have Git installed, complete the following before proceeding: [Git installation](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git) & [First-time Git setup](https://git-scm.com/book/en/v2/Getting-Started-First-Time-Git-Setup)

Once you have an account and the Heroku CLI installed you have to login from the terminal

```
> heroku login
```

These are the instructions to deploy a Frontity project on Heroku, once you are ready to deploy your project:

### Create a [heroku app](https://devcenter.heroku.com/articles/getting-started-with-nodejs#deploy-the-app)

Create an app on Heroku from the root of your project

```
> heroku create
```

Heroku will generate a random name for your app (`shielded-gorge-51896` in the example), or you can pass a parameter to specify your own app name.

```
⬢  my-frontity-project  master ⦾ heroku create
 ›   Warning: heroku update available from 7.25.0 to 7.38.2.
Creating app... done, ⬢ shielded-gorge-51896
https://shielded-gorge-51896.herokuapp.com/ | https://git.heroku.com/shielded-gorge-51896.git
```

When you create an app, a remote git repository (called `heroku`) is also created on Heroku and associated with your local git repository.

```
⬢  my-frontity-project  master ⦾ git remote -v
heroku    https://git.heroku.com/shielded-gorge-51896.git (fetch)
heroku    https://git.heroku.com/shielded-gorge-51896.git (push)
origin    git@github.com:frontity-demos/my-frontity-project.git (fetch)
origin    git@github.com:frontity-demos/my-frontity-project.git (push)
```

### Add a `start` script

Heroku will automatically execute your `start` script so add the following to your `scripts` section in the `package.json` file at the root of your project.

```javascript
"scripts": {
  "start": "frontity serve --port $PORT",
  "dev": "frontity dev",
  "build": "frontity build",
  "serve": "frontity serve"
},
```

Heroku will automatically execute your `build` script before starting your app. You should have this one already defined in your project.

> Notice how we're using $PORT to read this value from an environment variable. It is because Heroku will set a different port for each process and that port will be stored in a `PORT` environment variable

### Deploy

The way to deploy to Heroku by is pushing to the `heroku` git remote, so we can do

```
git push heroku master
```

You should get something like this

```bash
⬢  my-frontity-project  master ⦾ git push heroku master
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 4 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 290 bytes | 290.00 KiB/s, done.
Total 3 (delta 2), reused 0 (delta 0)
remote: Compressing source files... done.
remote: Building source:
remote:
remote: -----> Node.js app detected
remote:
remote: -----> Creating runtime environment
remote:
remote:        NPM_CONFIG_LOGLEVEL=error
remote:        NODE_ENV=production
remote:        NODE_MODULES_CACHE=true
remote:        NODE_VERBOSE=false
remote:
remote: -----> Installing binaries
remote:        engines.node (package.json):  unspecified
remote:        engines.npm (package.json):   unspecified (use default)
remote:
remote:        Resolving node version 12.x...
remote:        Downloading and installing node 12.16.2...
remote:        Using default npm version: 6.14.4
remote:
remote: -----> Restoring cache
remote:        - node_modules
remote:
remote: -----> Installing dependencies
remote:        Installing node modules (package.json + package-lock)
remote:        audited 10234 packages in 7.144s
remote:
remote:        15 packages are looking for funding
remote:          run `npm fund` for details
remote:
remote:        found 0 vulnerabilities
remote:
remote:
remote: -----> Build
remote:        Running build
remote:
remote:        > my-frontity-project@1.0.0 build /tmp/build_00b81abd8c2a36d3f2525857753e0188
remote:        > frontity build
remote:
remote:        mode: production
remote:
remote:        Building es5 bundle
remote:        Building module bundle
remote:        Building server bundle
remote:
remote:
remote: -----> Caching build
remote:        - node_modules
remote:
remote: -----> Pruning devDependencies
remote:        audited 10234 packages in 6.44s
remote:
remote:        15 packages are looking for funding
remote:          run `npm fund` for details
remote:
remote:        found 0 vulnerabilities
remote:
remote:
remote: -----> Build succeeded!
remote: -----> Discovering process types
remote:        Procfile declares types     -> (none)
remote:        Default types for buildpack -> web
remote:
remote: -----> Compressing...
remote:        Done: 52.3M
remote: -----> Launching...
remote:        Released v14
remote:        https://shielded-gorge-51896.herokuapp.com/ deployed to Heroku
remote:
remote: Verifying deploy... done.
To https://git.heroku.com/shielded-gorge-51896.git
   ee9c4d2..ab9b152  master -> master
```

*Heroku* will assign you a domain (something like *your-project-name.herokuapp.com*) that will allow you to check your site online

## Deploy a production site

To [deploy your site under a custom domain in Heroku](https://devcenter.heroku.com/articles/custom-domains) you have to...

1. Add your custom domain in your Heroku app
2. Register a DNS record with your domain provider

...before deploying it

### Add your custom domain in your Heroku app

With the command `heroku domains:add` you can add a specific custom domain in your Heroku app

for example by doing:

```
heroku domains:add heroku domains:add www.variables-demo.com
```

you should get something like this

```
⬢  my-frontity-project  master ⦾ heroku domains:add www.variables-demo.com
 ›   Warning: heroku update available from 7.25.0 to 7.38.2.
Adding www.variables-demo.com to ⬢ shielded-gorge-51896... done
 ▸    Configure your app's DNS provider to point to the DNS Target damp-whale-rln632baq4jdhcj5aw495bst.herokudns.com.
 ▸    For help, see https://devcenter.heroku.com/articles/custom-domains

The domain www.variables-demo.com has been enqueued for addition
 ▸    Run heroku domains:wait 'www.variables-demo.com' to wait for completion
```

### Add a [`CNAME`](https://devcenter.heroku.com/articles/custom-domains) in your domain provider's DNS settings

Once you have added your domain to your Heroku app, you can use the command `heroku domains` to see the value for the `CNAME` record that you have to set in your domain settings.

```
⬢  my-frontity-project  master ⦾ heroku domains
 ›   Warning: heroku update available from 7.25.0 to 7.38.2.
=== shielded-gorge-51896 Heroku Domain
shielded-gorge-51896.herokuapp.com

=== shielded-gorge-51896 Custom Domains
Domain Name             DNS Record Type  DNS Target
──────────────────────  ───────────────  ─────────────────────────────────────────────────
www.variables-demo.com  CNAME            damp-whale-rln632baq4jdhcj5aw495bst.herokudns.com
```

With this info you can [add a CNAME](https://devcenter.heroku.com/articles/custom-domains) in your domain provider's DNS settings.

{% hint style="info" %}
If you don't know how to do this, contact your domain provider (GoDaddy, CloudFlare, etc)
{% endhint %}

### Deploy

Then, deploy Frontity using this command (from the root of your project):

```
> git push heroku master
```

> If no changes are detected you may have to do: `npx frontity build` → to generate a new build `git commit --allow-empty` → to force a empty commit `git push heroku master` → to push this lateste build into heroku and launch its deploy process

{% hint style="info" %}
Still have questions? Ask [the community](https://community.frontity.org/)! We are here to help 😊
{% endhint %}


# Isomorphic React

When developing a Frontity project or package the React code (used in your custom theme) should be [isomorphic](https://www.smashingmagazine.com/2015/04/react-to-the-future-with-isomorphic-apps/) (also called universal).

This means that **all the code in a Frontity project should be prepared to be executed both on the server-side and on the client-side**.

{% hint style="info" %}
This is especially important when we import npm packages for use in our Frontity project. For example, [`fetch`](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch) is native in client-side only and so is not available server-side. Therefore [a `fetch` that works in both client-side and server-side](https://api.frontity.org/frontity-packages/core-package/frontity#fetch) is recommended.
{% endhint %}

{% hint style="info" %}
Another example is the [`window` object](https://developer.mozilla.org/en-US/docs/Web/API/Window). You should not try to access any of the properties or methods available in the `window` object from code that is going to be executed on the server, as the code will fail since the `window` object is only available in the browser.
{% endhint %}

## Table of Contents

* [Server-side Navigation and client-side Navigation](/isomorphic-react#server-side-navigation-and-client-side-navigation)
* [Initialization of a Frontity app](/isomorphic-react#initialization-of-a-frontity-app)
  * [Frontity Lifecycle Initialization Actions](/isomorphic-react#frontity-lifecycle-initialization-actions)
* [Creating different entry points](/isomorphic-react#creating-different-entry-points)
* [Server-side code and client-side code](/isomorphic-react#server-side-code-and-client-side-code)
  * [Server-side only code](/isomorphic-react#server-side-only-code)
  * [Client-side only code](/isomorphic-react#client-side-only-code)
  * [Both server-side and client-side code](/isomorphic-react#both-server-side-and-client-side-code)

## Server-side Navigation and client-side Navigation

Every time we access a page on a Frontity site the first load is rendered on the server. Once the initial server-side render (SSR) is complete the HTML is sent to the client (along with React hydration) and then the ensuing navigation is done in the client-side (CSR). ([This enables your site to remain SEO friendly, while also maintaining a good UX](https://medium.com/capital-one-tech/why-everyone-is-talking-about-isomorphic-universal-javascript-and-why-it-matters-38c07c87905)).

Let's take a look at some possible navigation examples as they would occur in an Isomorphic React App:

**Scenario A (SSR)**

If we enter the URL `/home` in the browser's address bar and press Enter, then the page with the slug `home` is rendered in the server and served to the client. If we enter the URL `/contact` in the browser's address bar and press Enter, then the page with the slug `contact` is rendered in the server and served to the client.

In these two cases, a SSR (Server-Side Render) process has taken the React code and created the proper HTML with the proper content that is "served" to the client so it can be displayed to the user.

**Scenario B (SSR & CSR)**

But consider the case where we enter the URL `/home` in the browser's address bar and press Enter, and then once the page has loaded in the browser we go to the `/contact` URL from a link in the page.

What then happens is:

* the page with the slug `home` is rendered in the server and served to the client *(as before)*
* the page with the slug `contact` is this time rendered *in the client* and displayed to the user

In this "Scenario B", we can call the navigation process to get to the `home` page *"server-side Navigation"* and the navigation process to get to the `contact` page *"client-side Navigation"*

We can also refer to these as a *Server-Side Render* process (SSR) in the case of the `home` page, and a *Client-Side Render* process (CSR) in the case of the `contact` page.

![Isomorphic Workflow](https://frontity.org/wp-content/uploads/2021/06/frontity-react-isomorphic-apps-2.png)

[*Open drawing*](https://excalidraw.com/#json=4939822133149696,WM4aYk6GSv47pncKIs365Q)

So, as you can see from the above image, this is something that we need to bear in mind when developing a React theme with Frontity.

Luckily, **ALL** the tools included with Frontity provide this isomorphic behavior out of the box (i.e. they ensure behavior that works both on the server-side and on the client-side).

## Initialization of a Frontity app

The initialization (or Bootstraping) of a Frontity site happens when we do *Server-side Navigation* (Server-Side Render, SSR), this when we do either:

* type a URL of a Frontity site in the browser's address bar and press Enter, or
* reload a URL of a Frontity site (e.g. by hitting the `refresh` button in the browser on a page that has been rendered in CSR)

In this process (i.e. the request of `/home` in the diagram above) Frontity does the following:

1. Server generates the HTML for the requested page
2. Server sends the HTML to the client
3. Client hydrates the React app in top of the HTML rendered

Once these have occurred React can then take full control of the app and the navigation of the site (through clicks on links) will be handled in the client-side (i.e. the request of `/contact` in the diagram above):

1. Client (React) requests the data from the WordPress server *(if not already in the state)*
2. Client (React) displays the proper HTML with the proper content and data

### Frontity Lifecycle Initialization Actions

Frontity provides several actions, namely [Frontity Lifecycle Initialization Actions](https://docs.frontity.org/learning-frontity/actions#frontity-lifecycle-initialization-actions), that are executed at specific moments in the initialization process. You can 'hook' functions onto these actions to ensure that they are executed at the appropriate moments in this lifecyle.

Some of these actions that you can 'hook' your code onto occur on the server-side, and some on the client-side - thus giving you the ability to specify not only *when* your code is executed, but also *where* it is executed.

On the Server Side:

1. Execution of the `init` action
2. Execution of the `beforeSSR` action
3. Server generates the HTML of the requested page
4. Execution of the `afterSSR` action
5. Server sends the HTML to the client

On the Client Side:

1. Execution of the `init` action (again)
2. Execution of the `beforeCSR` action
3. Client hydrates the React app in top of the HTML rendered
4. Execution of the `afterCSR` action

![Frontity Lifecycle Initialization Actions](https://frontity.org/wp-content/uploads/2021/06/Frontity-Lifecycle-Initialization-Actions.png)

## Creating different entry points

By default Frontity will create the final bundles that will be used in the server-side and in the client-side from the `index.js` file in the `src` folder of the theme package you're using for your Frontity project.

However, you can actually create two different [entry points](https://docs.frontity.org/learning-frontity/packages#entry-points) for your React theme package in Frontity. So, instead of having an `index.js` you can have the following two files:

* `client.js` → the entry point of our app when client-side takes controls
* `server.js` → the entry point of our app when server-side takes controls

If Frontity finds those files, it will import the `server.js` one in Node.js and the `client.js` one in the browser, and it will ignore the `index.js` file - which can, nevertheless, still exist.

You can define the appropriate [Frontity Lifecycle Initialization Actions](https://docs.frontity.org/learning-frontity/actions#frontity-lifecycle-initialization-actions) in either, or both, of these files (`client.js` and `server.js`), or in the default `index.js`.

{% hint style="info" %}
Using `beforeSSR` is independent of using a `server.js` file. You can add a `beforeSSR` function to your `index.js` and it works fine. The code, of course, will make it into the client bundle, but the action won’t be called there (unless you call it manually).
{% endhint %}

The main use cases where you may want to use two separate `client.js` and `server.js` files are:

* If you need to access Node.js libraries, such as `"fs"` or `"path"` , because they will fail if present in the client bundle (`"dot-env"` for accessing environment variables, for example).
* If the code contains something that cannot be exposed to the client, for example authentication details such as a hardcoded API key.
* If you are using a heavy library on the server that will increase the size of the client bundle unnecessarily. For example, you can use  [`he`](https://github.com/mathiasbynens/he)  to decode entities in the `server.js`, but it [weighs in at 73Kbs](https://bundlephobia.com/result?p=he@1.2.0). You can therefore use [`new DOMParser().parseFromString`](https://developer.mozilla.org/en-US/docs/Web/API/DOMParser), which is available in the browser and so is essentially free, in the `client.js` instead.

## Server-side code and client-side code

Due to the isomorphic nature of sites built with Frontity there will be some parts of the code of your Frontity project that will be executed only on the server, some parts that will be executed only on the client (i.e. the browser), and some parts that will be executed on both.

[*Open diagram*](https://excalidraw.com/#json=5101565044064256,fH-YZ9augphZgj4jF_u4IQ)

### Server-side only code

During the initialization of a Frontity app, the following parts of the code are executed only on the server

* The [`server.js` file](/isomorphic-react#creating-different-entry-points)
* Functions "hooked" onto the [`beforeSSR`](https://docs.frontity.org/learning-frontity/actions#beforessr-server-only) and [`afterSSR`](https://docs.frontity.org/learning-frontity/actions#beforessr-server-only) actions

As the [`frontity.settings.js` file](/learning-frontity/settings) is executed at Build Time, this file also has access to server-side packages and environment variables.

{% hint style="info" %}
As the code only runs on the server we can safely make use of environment variables inside of, for example, the `beforeSSR` action.
{% endhint %}

![Server-side only code](https://frontity.org/wp-content/uploads/2021/06/server-side-code.png)

### Client-side only code

During the initialization of a Frontity app, the following parts of the code are executed only on the client-side (i.e. in the Browser).

* The [`client.js` file](/isomorphic-react#creating-different-entry-points)
* Functions "hooked" onto the [`beforeCSR`](https://docs.frontity.org/learning-frontity/actions#beforecsr-client-only) and [`afterCSR`](https://docs.frontity.org/learning-frontity/actions#aftercsr-client-only) actions

When components are “hydrated”, and also whenever any *Client-side Navigation* occurs, any hook defined in a React component (such as `useEffect`) will also be executed only on the client-side.

{% hint style="info" %}
This means that we can safely make use of, for example, the [`window` object](https://developer.mozilla.org/en-US/docs/Web/API/Window) or the native [`fetch`](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch) inside of the `useEffect` hook.
{% endhint %}

![Client-side only code](https://frontity.org/wp-content/uploads/2021/06/client-side-code.png)

### Both server-side and client-side code

During the initialization of a Frontity app the function "hooked" onto the [`init`](https://docs.frontity.org/learning-frontity/actions#init-client-and-server) action of the [`index.js` file](/isomorphic-react#creating-different-entry-points) is executed in both the server and the client-side.

The rest of the code inside the React components in the project will be executed either server-side or client-side depending on if we're doing Server-Side Navigation or Client-Side Navigation.

{% hint style="info" %}
This means that in this part of the code we should use isomorphic versions of libraries, for example using an isomorphic [`fetch`](https://api.frontity.org/frontity-packages/core-package/frontity#fetch) (as [the one](https://api.frontity.org/frontity-packages/core-package/frontity#fetch) provided by the [`frontity`](https://api.frontity.org/frontity-packages/core-package/frontity) package) to fetch resources from the network as it'll work in both server and client-side.
{% endhint %}

![Both Client-side and Server-side code](https://frontity.org/wp-content/uploads/2021/06/server-client-side-code.png)


# ⚡️ Perfomance

Frontity projects are fast by default. Frontity framework will help you to improve the performance and speed of your site built with a stack consisting of React and WordPress. But Frontity framework on its own cannot assure the best performance of your site as there are some elements involved in the final perfomance that are out of the scope of Frontity.

In this section, we'll provide guides to some of the strategies and patterns that you can apply to your Frontity sites in order to improve even more the performance of your Frontity site:

* [Caching](/performance/caching)
* [Link prefetching](/performance/link-prefetching)
* [Lazy Loading](/performance/lazy-loading)
* [Code Splitting](/performance/code-splitting)

{% hint style="info" %}
[These diagrams](https://excalidraw.com/#json=6167540090798080,cvhnsErHXsqarOVT82YgLw) can help you understand how Frontity, the WordPress + React stack and the proper performance strategies may improve the final performance of your project (besides having a great content creation, development and user experience) in both [Decoupled](/architecture/decoupled-mode) and [Embedded](/architecture/embedded-mode) Mode
{% endhint %}


# Caching

{% hint style="info" %}
With a good caching strategy your Frontity project can be as performant as a static site.
{% endhint %}

In Frontity projects we can implement two main types of caching:

* **Distributed Caching (CDN)**: The responses of requests are cached and distributed on a Network of Servers (CDN) so next requests for the same content can be directly delivered from the closest server from your location
* **Server Caching (WordPress Cache Plugins)**: The responses of requests are cached and stored in the server so next requests for the same content can be directly delivered from memory saving processing time. This strategy will mostly be managed by WordPress Cache Plugins in Frontity Architectures.&#x20;

![](https://frontity.org/wp-content/uploads/2021/05/cdn-server-caches-embdeded-mode.png)

## Table of contents

* [Distributed caching (CDN)](/performance/caching#distributed-caching-cdn)
  * [CDN for Frontity servers](/performance/caching#cdn-for-frontity-servers)
  * [CDN for WordPress servers](/performance/caching#cdn-for-wordpress-servers)
* [Server caching](/performance/caching#server-caching)
  * [Server caching for URL requests in WordPress servers](/performance/caching#server-caching-for-url-requests-in-wordpress-servers)
  * [Server caching for REST API requests in WordPress servers](/performance/caching#server-caching-for-rest-api-requests-in-wordpress-servers)

## Distributed caching (CDN)

Adding a cache layer to cache your URL requests is the most effective way to speed up the delivery of your pages as most of them will be delivered from a server very close to the user's location and no processing time will be required

Based on our experience working with media publishers, we recommend that you select a service offering the [**stale-while-revalidate**](https://www.keycdn.com/blog/keycdn-supports-stale-while-revalidate) cache directive, which is the best cache technique for Frontity projects.

### CDN for Frontity servers

If you're using [**Decoupled Mode**](/architecture/decoupled-mode#caching-in-decoupled-mode) (main domain pointing to the Frontity server) our recommendation is that you host your Frontity site with [**Vercel**](https://vercel.com/) that includes a distributed cache network.

In [their own words about caching](https://vercel.com/docs/edge-network/caching):

> The [Vercel Edge Network](https://vercel.com/docs/edge-network/overview) caches your content at the edge in order to serve data to your users as fast as possible.

Vercel includes both a CDN and the `stale-while-revalidate` cache directive (which they call [Serverless Pre-Rendering](https://vercel.com/blog/serverless-pre-rendering)). Their service is the quickest and easiest to set up, and you can follow our guide to [deploying Frontity using Vercel](/deployment/deploy-using-vercel).

If you prefer another hosting or want to deploy your Frontity site as a [Serverless](https://hackernoon.com/what-is-serverless-architecture-what-are-its-pros-and-cons-cc4b804022e9) function by using services such as [AWS Lambda](https://aws.amazon.com/lambda), [Netlify](https://www.netlify.com/) or [Google Functions](https://cloud.google.com/functions/), we highly recommend you to add a CDN (such as a [Cloudflare](https://www.cloudflare.com/es-es/)) as it is key to improve your web performance.

{% hint style="info" %}
We have tested many solutions for CDN and `stale-while-revalidate`, and we consider that the best options for this approach are [KeyCDN](https://www.keycdn.com) and [StackPath](https://www.stackpath.com/).
{% endhint %}

### CDN for WordPress servers

If you're using [**Embedded Mode**](/architecture/embedded-mode#caching-in-embedded-mode) your main domain will point to your WordPress installation. In this architecture all the Cache solutions you were using for your WordPress will still be valid for Frontity using this Embedded Mode.

In WordPress there are several [solutions](https://wpbuffs.com/wordpress-cdn-plugins/) and [plugins](https://wordpress.org/plugins/tags/cdn/) to add a CDN Cache Layer to your site. This CDN implementation can be managed directly from your hosting provider or from a WordPress plugin

## Server caching

Besides using a CDN to cache your requests, another cache layer can be added at a Server level. This cache will create a local copy of the requests so next time the same page is requested it will be delivered from the local copy (saving processing time)

### Server caching for URL requests in WordPress servers

In the [**Embedded Mode**](/architecture/embedded-mode#caching-in-embedded-mode), the main domain is connected to the WordPress server which will redirect the to the Frontity Web Server to get the proper HTML based on the data of the WP REST API.

In this case, a service to cache the URL requests managed by WordPress can be implemented via a WordPress plugin. This can be done easily though some of the [cache plugins available for WordPress](https://www.wpbeginner.com/plugins/best-wordpress-caching-plugins/)

If the URL requested is cached, the plugin will return the content and no further requests will be done to the Frontity Server (or the WP REST API)

### Server caching for REST API requests in WordPress servers

Caching REST API requests is highly recommended in both **Decoupled & Embedded Mode** asi it will also speed up the general response time of your site

This can also be done easily though a [cache plugin that supports REST API](https://wordpress.org/plugins/wp-rest-cache/) such as [Simple Cache plugin](https://wordpress.org/plugins/simple-cache/)

{% hint style="info" %}
With [Simple Cache plugin](https://wordpress.org/plugins/simple-cache/) you'll have to [turn REST API and Headers options ON](https://frontity.org/wp-content/uploads/2021/05/simple-cache-settings.png), so REST API requests are properly cached
{% endhint %}


# Link prefetching

## What is prefetching?

Link prefetching is a strategy to improve the perceived performance of page loading.

We cannot improve on the explanation of prefetching provided by [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/HTTP/Link_prefetching_FAQ). They describe it thus:

> Link prefetching is a browser mechanism, which utilizes browser idle time to download or prefetch documents that the user might visit in the near future. A web page provides a set of prefetching hints to the browser, and after the browser is finished loading the page, it begins silently prefetching specified documents and stores them in its cache. When the user visits one of the prefetched documents, it can be served up quickly out of the browser's cache.

Commonly documents and assets are prefetched using a `<link>` element containing a `rel="prefetch"` attribute. For example:

```markup
<link rel="prefetch" href="/images/my-pic.jpg">
```

The `rel="prefetch"` attribute is a 'hint' to the browser that the specified URL should be prefetched. It may or may not be prefetched depending on whether the browser has sufficient idle time to do so before the user actually clicks the link.

This works well for traditional sites where each new URL involves an HTTP request and a page refresh. Performance is improved because prefetched documents and assets are already in the browser cache and so don't need to be fetched at the time that the link is clicked.

In addition to `prefetch` the `rel` attribute of the `<link>` element can take different values depending on the type of prefetching required:

* dns-prefetch
* preconnect
* prefetch
* subresource
* prerender

[This CSS-tricks article](https://css-tricks.com/prefetching-preloading-prebrowsing/) provides a comprehensive overview of these different prefetching options.

{% hint style="info" %}
Care should be taken when implementing prefetching and consideration should be given to the likelihood that the document or asset will be needed in the near future, i.e. how likely it is that a particular link will be the next one to be clicked.
{% endhint %}

## Implementing link prefetching strategies with Frontity

For JavaScript based SPA applications such as Frontity the situation is slightly different. No additional elements are needed in the markup, and the prefetching is performed with JavaScript. In such cases data is prefetched and stored in the application's "state".

We will describe two methods for implementing link prefetching in Frontity. The first will use the `<Link />` component provided by Frontity. The second will demonstrate how to create your own component implementing link prefetching.

### Frontity's `<Link>` component

Frontity's [`<Link />` component](https://api.frontity.org/frontity-packages/collections-packages/components#link) supports prefetching. The prefetching strategy that it adopts is determined by the value of the property `state.theme.autoPrefetch`.

The possible values for `state.theme.autoPrefetch` are:

| Value     | Description                                       |
| --------- | ------------------------------------------------- |
| `no`      | No auto prefetch.                                 |
| `hover`   | Prefetches links on hover.                        |
| `in-view` | Prefetch links currently visible in the viewport. |
| `all`     | Prefetches all internal links on the page.        |

The value of `state.theme.autoPrefetch` could then be set in the `frontity.settings.js` file, for example:

```javascript
const settings = {
  // Other settings...
  packages: [
    {
      name: "my-theme",
      state: {
        theme: {
          autoPrefetch: "hover", // values: no | hover | in-view | all
        },
      },
    },
    // Other packages...
  ],
};
```

A component that uses Frontity's `<Link />` component should import it from `@frontity/components`:

```javascript
import Link from "@frontity/components/link";
```

Here is a short video demonstrating prefetching with Frontity's `<Link>` component:

{% embed url="<https://www.youtube.com/watch?v=EUt8x5oglmI>" %}

{% hint style="info" %}
**Note that** for links present in the content to benefit from the prefetching strategy of the `<Link>` component the content should be processed by the [`html2react` package](https://api.frontity.org/frontity-packages/features-packages/html2react). See [this page](https://tutorial.frontity.org/part7-finishing-touches/use-the-html2react-component) in our tutorial for a detailed example illustrating the steps that need to be taken.
{% endhint %}

### Creating your own link component with prefetching

If you wish to create your own link component that also implements auto-prefetching based on the value of a `state.theme.autoPrefetch` property then a possible implementation could look like this:

```javascript
import React, { useEffect } from "react";
import { connect } from "frontity";

const Link = ({
  state,
  actions,
  link,
  className,
  children,
  rel,
  "aria-current": ariaCurrent,
  onClick: onClickProp,
}) => {
  // Check if the link is an external or internal link
  const isExternal = link.startsWith("http");

  // Prefetch the link's content when it mounts and autoPreFetch is set to `true`
  useEffect(() => {
    if (!isExternal) {
      if (state.theme.autoPrefetch === "all") actions.source.fetch(link);
    }
  }, []);

  const onClick = (event) => {
    // Do nothing if it's an external link
    if (isExternal) return;

    event.preventDefault();
    // Set the router to the new url.
    actions.router.set(link);

    // Scroll the page to the top
    window.scrollTo(0, 0);

    // if the menu modal is open, close it so it doesn't block rendering
    if (state.theme.isMobileMenuOpen) {
      actions.theme.closeMobileMenu();
    }

    if (onClickProp) {
      onClickProp(event);
    }
  };

  return (
    <a
      // ref={ref}
      href={link}
      onClick={onClick}
      className={className}
      aria-current={ariaCurrent}
      rel={isExternal ? "noopener noreferrer" : rel}
      onMouseEnter={() => {
        // Prefetch the link's content when the user hovers on the link
        if (state.theme.autoPrefetch === "hover" && !isExternal)
          actions.source.fetch(link);
      }}
    >
      {children}
    </a>
  );
};

export default connect(Link);
```

This uses `useEffect` to call `actions.source.fetch(link)` to fetch the data if the value of `state.theme.autoPrefetch` is "all", and if the value is "hover" then it calls `actions.source.fetch(link)` to fetch the data when the `onMouseEnter` event occurs.


# Lazy Loading

## Lazy loading

As [defined by MDN](https://developer.mozilla.org/en-US/docs/Web/Performance/Lazy_loading)

> Lazy loading is a strategy to identify resources as non-blocking (non-critical) and load these only when needed. It's a way to shorten the length of [the critical rendering path](https://developer.mozilla.org/en-US/docs/Web/Performance/Critical_rendering_path), which translates into reduced page load times.

So, by applying lazy-loading strategies your page will load much faster as the assets will be loaded only when they're really needed (when they first appear in the viewable area for the user).

A good example of this are images: you won't probably need to load all the images in your page as you only need those images that appear in the viewable area for the user on first load. A better strategy is to load only the images that are in the viewable area for the user, and then load those images as they enter into this viewable area (if the user do not scroll, those images will never be loaded).

The same strategy can be applied to iframes and other resources that require a request to the server.

## How to apply lazy-loading in Frontity projects

Frontity provides the [`<Image />`](https://api.frontity.org/frontity-packages/collections-packages/components#image) and [`<Iframe />`](https://api.frontity.org/frontity-packages/collections-packages/components#iframe) React components that adds lazy-loading to them. They're available through the [`@frontity/components`](https://api.frontity.org/frontity-packages/collections-packages/components) package.

The [`<Link>`](https://api.frontity.org/frontity-packages/collections-packages/components#link) component provides a sort-of lazy-loading behaviour called [**link prefeching**](https://docs.frontity.org/performance/link-prefetching).

Finally, with the [Intersection Observer Hooks](https://api.frontity.org/frontity-packages/collections-packages/hooks/intersection-observer-hooks) provided by the [`@frontity/hooks`](https://api.frontity.org/frontity-packages/collections-packages/hooks) package you can create your custom logic to be triggered only when the React element reaches the viewable area.


# Code Splitting

Code Splitting lets you split your code into various bundles, instead of using a single one with all the code. These smaller bundles are dynamically loaded at runtime depending on the URL.

**If used properly, this can mean important performance gains.**

The bundles can be loaded on demand or in parallel, which allows you to just load the code that is currently needed by the user. This way you can avoid loading heavy code until it is required and reduce the amount of code during the initial load.

Frontity has configured everything to make Code Splitting really easy.

To use it you just have to import the `{ loadable }` module from `frontity` and then dynamically import the React component that you don't want to be loaded until it is strictly needed.

```jsx
import { loadable } from "frontity";
const OtherComponent = loadable(() => import('./OtherComponent'))

function MyComponent() {
  return (
    <div>
      <OtherComponent />
    </div>
  )
}
```

## Code Splitting Use Case: Comments

Imagine you are using a big library for showing your comments. You will want to load it just when it is needed, so it doesn't increase the bundle size if that React component is not loaded.

Code splitting lets you do it.

You have to use `loadable` with a dynamic `import()` inside:

```jsx
import { loadable } from "frontity";
import Content from "./components/content";

// Thanks to loadable we prevent comments from loading until it's needed.
const HeavyComments = loadable(() => import('./components/comments'));

const Post = ({ state }) => (
    <>
        <Content />
        {state.comments.areOpened && <HeavyComments />}
    </>
);

export default connect(Post);
```

Instead of using the normal `import ... from`.

```jsx
import { loadable } from "frontity";
import Content from "./components/content";
import HeavyComments from "./components/comments";

const Post = ({ state }) => (
    <>
        <Content />
        {state.comments.areOpened && <HeavyComments />}
    </>
);

export default connect(Post);
```

By default, `state.comments.areOpened === false` .

The heavy library used for comments won't be loaded until you change the state to `true` such as when, for example, you click a button to open the comments. At that moment the code for that React component is downloaded and executed.

If we don't use `loadable` , the `<HeavyComments>` component is included in the main bundle and loaded at the initial page load, even if the comments are never shown.

## Loadable Components Documentation

For managing the Code Splitting, Frontity has integrated and configured [Loadable Components](https://www.smooth-code.com/open-source/loadable-components/docs/code-splitting/).

[![loadable components](https://frontity.org/wp-content/uploads/2021/04//loadable-components.png)](https://loadable-components.com/docs/getting-started/)

If you want to go deeper, you should take a look at [**their docs**](https://loadable-components.com/docs/getting-started/). You don't need to read the docs on how to install and configure Loadable Components since we have already done that work for you. Below are concepts that are interesting and helpful to read up on:

* What is [*Code Splitting*](https://loadable-components.com/docs/code-splitting/)?
* Most of the time, you want to [*prefetch*](https://loadable-components.com/docs/prefetching/) a component, it means it will be loaded when the browser is idle.&#x20;
* Specify a [*Fallback*](https://loadable-components.com/docs/fallback/) in loadable options.&#x20;
* Handle loading errors with [*Error Boundaries*](https://www.smooth-code.com/open-source/loadable-components/docs/error-boundaries).
* To avoid flashing a loader if the loading is very fast, you could implement a minimum [*Delay*](https://www.smooth-code.com/open-source/loadable-components/docs/delay/)
* Infinite loading is not good for user experience, to avoid it implementing a [*timeout*](https://www.smooth-code.com/open-source/loadable-components/docs/timeout/) is a good workaround.&#x20;
* Use [Library Splitting](https://www.smooth-code.com/open-source/loadable-components/docs/library-splitting/) to defer the loading of a library.
* Create a reusable Loadable Component by using a [*Dynamic Import*](https://www.smooth-code.com/open-source/loadable-components/docs/dynamic-import/).


# SEO

Due to the Isomorphic nature of React apps in Frontity, the first load of any site will be rendered by the server using the React components in the project. Frontity allows you to optimize the SEO performance of your site and customize how your site is indexed by search engine crawlers.

By default, Frontity will deliver to your browser a fully populated and well-formed [HTML file generated from your React code](https://github.com/frontity/docs/tree/8ebc1b05f6cbe3607b1cf9ec35da788d8b35bfe5/architecture.md). This reduces the time required for the first contentful paint and ensures a good SEO score.

{% hint style="info" %}
To take advantage of all the SEO benefits you already have in your WordPress (sitemaps, cache plugins, CORS headers, redirections, etc...) the [Embedded Mode of Frontity](/architecture/embedded-mode#features-of-the-embedded-mode) is recommended
{% endhint %}

{% hint style="info" %}
[These diagrams](https://excalidraw.com/#json=6167540090798080,cvhnsErHXsqarOVT82YgLw) can help you understand how Frontity, the WordPress + React stack and the proper performance strategies may improve the final performance and SEO of your project (besides having a great content creation, development and user experience) in both [Decoupled](/architecture/decoupled-mode) and [Embedded](/architecture/embedded-mode) Mode
{% endhint %}

But that's not all. With Frontity you can also customize:

* Meta tags&#x20;
* `robots.txt`

## Header meta tags

You can include the meta tags generated by your WordPress SEO plugin in your React app so they can be properly rendered in the `<head>` section of the final HTML

In order to do that you have to use:

* The [REST API - Head Tags](https://api.frontity.org/frontity-plugins/rest-api-head-tags) **WordPress plugin**. This plugin has been developed by the Frontity team and it adds the meta tags generated by your WordPress SEO plugin to the REST API
* The [@frontity/head-tags](https://api.frontity.org/frontity-packages/features-packages/head-tags) **Frontity package**. This package is designed to automatically get all the data that the REST API Head Tags plugin exposes in the REST API

### The `<Head>` component

Besides the tags added through WordPress plugins you can also customize your `<head>` tags from Frontity. The [`<Head>` component](https://api.frontity.org/frontity-packages/core-package/frontity#head) provided by the [`frontity` package](https://api.frontity.org/frontity-packages/core-package/frontity) uses [React Helmet](https://github.com/nfl/react-helmet) internally, so you can work as if you were working with common HTML.

To adjust the `<head>`, you just have to import [`Head` from `frontity`](https://api.frontity.org/frontity-packages/core-package/frontity#head) and write inside `<Head>` all the tags you want. Usually, you will want to import it at the `index.js` of your theme, in order for it to be loaded on all your pages.

```jsx
import { Head } from "frontity";

const Theme = () => (
    <Head>
        <title>My awesome blog</title>
        <meta name="description" content="This blog is just for being awesome" />
        <html lang="en" />
        <link rel="canonical" href="https://example.com" />
    </Head>
);
```

You can, of course, use variables or include code outside `<Head>` that will be rendered normally.

```jsx
import { Head, connect } from "frontity";

const Theme = ({ state }) => {
    const data = state.source.get(state.router.link);
    return (
        <>
            <Head>
                <title>{state.frontity.title}</title>
                <meta name="description" content={state.frontity.description} />
                <html lang="en" />
                <link rel="canonical" href={state.router.link} />
            </Head>

            <div>
                {data.isFetching && <Loading />}
                {data.isArchive && <List />}
                {data.isPostType && <Post />}
                {data.is404 && <Page404 />}
            </div>
        </>
    );
};

export default connect(Theme);
```

That's all, you just have to configure it at your will. Frontity uses [React Helmet](https://github.com/nfl/react-helmet) internally. You should check its docs out in case you want to understand it better.

## `robots.txt`

A [`robots.txt`](https://support.google.com/webmasters/answer/6062608) file tells search engine crawlers which pages or files the crawler should or shouldn't request from your site.

You can add the `robots.txt` file at the root of your theme (next to the `frontity.settings.js` file) and when you build and deploy your app for production, it will be automatically picked up by the Frontity server and served at `https://your-site-url.xyx/robots.txt`.

You can also [check out our example](https://github.com/frontity/frontity/blob/1460e7c03ce3600f4f8ece0d6cf8fadb2bf9b526/examples/mars-theme-example/robots.txt) of a theme that is using a `robots.txt` file.

{% hint style="info" %}
Want to know more about **SEO & Headless WordPress**? Have a look at this [post](https://frontity.org/blog/seo-for-headless-wordpress-themes/)
{% endhint %}

{% hint style="info" %}
If you still have any questions about SEO in Frontity, please check out the [**community forum**](https://community.frontity.org), which is packed full of answers and solutions to all sorts of Frontity questions. If you don't find what you're looking for, feel free to start a new post.
{% endhint %}


# Guides

In this section we present a selection of guides that will help you to both work with, and to better understand, a variety of topics related to Frontity.

### [Setting the URL of the WordPress data source](/guides/setting-url-wordpress-source-data) ![](https://img.shields.io/badge/WORDPRESS-207399.svg) ![](https://img.shields.io/badge/SOURCE-207399.svg)

*This guide outlines the various different WordPress configuration scenarios that you might encounter and the things that need to be taken into account in order to properly set the URL of the WordPress data source.*

### [Using Environment Variables in a Frontity project](/guides/how-to-use-environment-variables-in-frontity) ![](https://img.shields.io/badge/ISOMORPHIC_REACT-207399.svg)

*This guide explains how to defined environment variables for a Frontity project and how to properly access these variables from the code.*

### [WordPress requirements for Frontity](/guides/what-are-the-requisites-of-wordpress-for-frontity) ![](https://img.shields.io/badge/WORDPRESS-207399.svg)

*This guide highlights some basic WordPress requirements needed for Frontity projects.*

### [URLs in a Migration from WordPress to Frontity Decoupled Mode](/guides/update-db-urls) ![](https://img.shields.io/badge/WORDPRESS-207399.svg) ![](https://img.shields.io/badge/DECOUPLED_MODE-207399.svg)

*This guide explains the issue that arise with regard to URLs when migrating a WordPress site to Frontity Decoupled Mode and how to resolve them.*

### [Frontity Query Options](/guides/frontity-query-options) ![](https://img.shields.io/badge/ISOMORPHIC_REACT-207399.svg) ![](https://img.shields.io/badge/SERVER-207399.svg)

*This guide explains what "Frontity Query Options" are and how to use them.*

### [Redirections with Frontity](/guides/redirections-with-frontity)  ![](https://img.shields.io/badge/WORDPRESS-207399.svg)

*This guide explains how to manage WordPress redirections with Frontity.*

### [Understanding a Frontity project](/guides/understanding-mars-theme)  ![](https://img.shields.io/badge/PROJECT-207399.svg)

*This guide will help you understand the structure of a Frontity project.*

### [Understanding Mars Theme](/guides/understanding-mars-theme-1) ![](https://img.shields.io/badge/PACKAGES-207399.svg) ![](https://img.shields.io/badge/THEMES-207399.svg)

*This guide will help you understand how `mars-theme` works.*

### [Add a new Frontity package or theme to your project](/guides/install-a-new-package)  ![](https://img.shields.io/badge/PROJECT-207399.svg) ![](https://img.shields.io/badge/PACKAGES-207399.svg) ![](https://img.shields.io/badge/THEMES-207399.svg)

*This guide will give through the process of installing and configuring new Frontity packages or themes for your project.*

### [Working with processors](/guides/using-processors) ![](https://img.shields.io/badge/PROCESSORS-207399.svg) ![](https://img.shields.io/badge/HTML2REACT-207399.svg)

*Learn how to use the `<html2react>` package and processors to customise the final markup that will be presented to the browser.*

### [How to process page-builder content in Frontity](/guides/processing-page-builder-content) ![](https://img.shields.io/badge/PROCESSORS-207399.svg) ![](https://img.shields.io/badge/GUTENBERG-207399.svg) ![](https://img.shields.io/badge/ELEMENTOR-207399.svg)

*This guide demonstrates how to use processors to render content generated by page-builders (such as Elementor, Gutenberg, etc...)*

### [Keep Frontity updated](/guides/keep-frontity-updated) ![](https://img.shields.io/badge/UPDATES-207399.svg)

*This guide will take through the process of updating your Frontity project to use latest versions of the Frontity packages you're using in your project.*

### [How to share your Frontity project](/guides/how-to-share-a-frontity-project) ![](https://img.shields.io/badge/REPOSITORY-207399.svg)

*This guide will give through the recommended workflow to work with a Frontity theme os package in a way it can be properly shared with the community.*

### [Troubleshooting guide](/guides/troubleshooting) ![](https://img.shields.io/badge/TROUBLESHOOTING-207399.svg)

*This guide offers solutions to common issues detected in Frontity projects.*

## JavaScript & React

If you are coming to Frontity from a different background, perhaps from the WordPress/PHP world, you may still not familiar with JavaScript or React.

We have prepared for you some guides to help get you start working with them:

### [JavaScript](/guides/javascript-basics)

*This guide will give you a better understanding of which JavaScript concepts are used in Frontity and a brief explanation of them.*

### [React](/guides/react-basic)

*This guide will take you through the React key concepts that are needed to be able to understand and create a project with Frontity.*

{% hint style="info" %}
If you have suggestions or ideas for other guides, please share them in the [community forum](https://community.frontity.org/c/framework-development/docs-and-tutorials/29).
{% endhint %}


# Setting the URL of the WordPress data source

The most important setting in a Frontity project is the WordPress installation that can be used as the source of data.

The format of the URL used to access the WordPress REST API varies depending on the type of WordPress installation used as the data source for the Frontity project, so the type of WordPress installation determines how this URL should be set in the Frontity configuration file `frontity.settings.js`.

The main property in `frontity.settings.js` needed for determining the URL of the WordPress data source is:

* **`state.source.url`**:  The URL of the WordPress. *Required*.

{% hint style="warning" %}
Mind how `state.source.url` should point to just the URL of your WordPress (i.e. `https://test.frontity.org`) and not the URL of your WordPress REST API (i.e. `https://test.frontity.org/wp-json`). The URL of of the REST API will be calculated by Frontity depending on each use case.
{% endhint %}

There are some other properties implied in determining this URL of the WordPress data source, but they need to be set only for specific use cases:

* `state.wpSource.isWpCom`:  A flag to indicate a special use case of WordPress.com sites (Personal or Premium plans). *It is not required for Free WordPress.com sites. Defaults to `false`.*
* `state.wpSource.prefix`: The prefix of the API. *Defaults to `/wp-json`. It is not used if `isWpCom` is `true`.*

{% hint style="info" %}
From [version 1.10](https://github.com/frontity/frontity/blob/dev/packages/wp-source/CHANGELOG.md#1100) of the `@frontity/wp-source` package, the property `state.source.api` *should never be set manually by the end users* (it will be computed from the properties mentioned above)
{% endhint %}

## WordPress scenarios

### A Self-hosted WordPress site

Most Frontity projects will use a self-hosted WordPress site ([wp.org](http://wp.org/)) with a custom domain, such as, for example, `https://test.frontity.org/`.

The recommended way to set this URL is via the `state.source.url` property.

```javascript
// frontity.settings.js
export default {
  packages: [
    {
      name: "@frontity/wp-source",
      state: {
        source: {
          url: "https://test.frontity.org",
        },
      },
    },
  ],
};
```

In this example the computed values would be:

* `state.source.api`:  `https://test.frontity.org/wp-json` *(value computed from `state.source.url` and `state.wpSource.prefix`)*.
* `state.wpSource.isWpCom`: `false` *(value derived from `state.source.api`)*

The same recommendation applies for custom domains used with a [WordPress.com Business plan](https://wordpress.com/support/business-plan/).

### A Free WordPress.com plan

Some Frontity projects may use a free WordPress.com installation with the URL pointing to a subdomain of WordPress.com, such as: `https://frontitytest.wordpress.com/`.

The recommended way to set this URL is also via the `state.source.url` property.

```javascript
// frontity.settings.js
export default {
  packages: [
    {
      name: "@frontity/wp-source",
      state: {
        source: {
          url: "https://frontitytest.wordpress.com/",
        },
      },
    },
  ],
};
```

In this example the computed values would be:

* `state.source.api`:  `https://frontitytest.wordpress.com/wp-json`*(value computed from `state.source.url` and `state.wpSource.prefix`)*.
* `state.wpSource.isWpCom`: `true` *(value derived `state.source.api`)*

### A Personal or Premium WordPress.com plan

A less frequent use case is where a Personal or Premium WordPress.com site is used as the data source. These plans allow you to use a custom domain, but in these cases the REST API is available via a different URL format.

The recommended way to set this URL is also via the `state.source.url` property, but in addition to this you also need to specify that it is a Personal or Premium WordPress.com plan installation by setting `state.wpSource.isWpCom` to `true`.

```javascript
// frontity.settings.js
export default {
  packages: [
    {
      name: "@frontity/wp-source",
      state: {
        source: {
          url: "https://test-premium-plan.frontity.org",
        },
        wpSource: {
          isWpCom: true
        } 
      },
    },
  ],
};
```

In this example the computed values would be:

* `state.source.api`: `https://public-api.wordpress.com/wp/v2/sites/test-premium-plan.frontity.org` *(value computed from `state.source.url` & `state.wpSource.isWpCom`)*

## Summary

All these scenarios and their different settings combinations are summarized in the following table

|                                | Free [wordpress.com](http://wordpress.com) | Personal or Premium [wordpress.com](http://wordpress.com) | Business [wordpress.com](http://wordpress.com) or [wp.org](http://wp.org) |
| ------------------------------ | ------------------------------------------ | --------------------------------------------------------- | ------------------------------------------------------------------------- |
| needs `state.source.url`       | YES                                        | YES                                                       | YES                                                                       |
| needs `state.wpSource.isWpCom` | NO                                         | YES                                                       | NO                                                                        |


# Using Environment Variables in a Frontity project

Environment variables are a very useful way of managing custom data that shouldn't be in the code. A prime example would be API KEYs or other authentication credentials for external APIs.

Since a [Frontity app is an Isomorphic React app](/isomorphic-react) we need to consider whether these environment variables should be accessible only to the code running server-side, or whether they should also be accessible to the code running client-side.

## Adding environment variables to a Frontity Project

In order to access environment variables from your Frontity project you can use a package such as [`cross-env`](https://www.npmjs.com/package/cross-env) or [`dot-env`](https://github.com/motdotla/dotenv).

If you use `cross-env`, you will not have to do anything special in Frontity. You just need to add it to your `package.json` scripts thus:

```javascript
{
  "scripts": {
    "dev": "cross-env MY_VARIABLE=xxx frontity dev",
    "serve": "cross-env MY_VARIABLE=xxx frontity serve",
    "build": "cross-env MY_VARIABLE=xxx frontity build"
  }
}
```

`dotenv` only runs in Node, so rather than using an `index.js` file you should instead [divide the content of your `index.js` file across two files, namely `client.js` and `server.js`](https://docs.frontity.org/learning-frontity/packages#entry-points).

{% hint style="info" %}
If `client.js` and `server.js` exist, the `index.js` file can also still exist but it will be ignored by both the server and the client.
{% endhint %}

So for `dotenv` we must create a `.env` file:

```bash
MY_VARIABLE=xxx
```

## Accessing the environment variables

### Private access to the environment variables ![](https://img.shields.io/badge/SERVER-7950f2.svg)

As [we can create different entry points](/isomorphic-react#creating-different-entry-points) for our Frontity theme package by creating separate `server.js` and `client.js` files (that will each only be executed in the appropriate environment), we are therefore able to privately access the content of the environment variable on the server (for example to perform a request to an external API and storing this data in the `state` so it can be accessed from your React components).

{% hint style="info" %}
[Here a demo](https://github.com/frontity-juanmaguitar/demo-frontity-env-variables-server) illustrating the use of an environment variable in `server.js`.
{% endhint %}

The content of the `server.js` file could be something like this:

```javascript
import { config } from "dotenv";
import { fetch } from "frontity";
import packageClient from "./client";

// Launch dotenv.
config();

export default {
  ...packageClient,
  actions: {
    theme: {
      ...packageClient.actions.theme,
      beforeSSR: async ({ state }) => {
        const {API_TMDB} = process.env
        const URL = `https://api.themoviedb.org/3/movie/550?api_key=${API_TMDB}`
        const detailsMovie = await fetch(URL)
          .then( response => response.json() )
        state.tmdb = { detailsMovie }
      }
    }
  },
};
```

In this example a `API_TMDB` environment variable is defined in a `.env` file included in that project

This method (`beforeSSR` defined in the `server.js`) will ensure that your API credentials are secure (i.e. they will not be part of the client bundle) and are only visible to the code running server-side. However, remember to take into account that this logic will be executed in the [initialization (or bootstrapping) of the Frontity app](/isomorphic-react#initialization-or-bootstraping-of-a-frontity-app) (i.e. for any page loaded the first time).

### Generic access to the environment variables ![](https://img.shields.io/badge/SERVER-7950f2.svg) ![](https://img.shields.io/badge/CLIENT-fd7e14.svg)

If you need to use the ENV variable also in the client, the best way is to add it to the `state`.

You can use `frontity.settings.js` or your package `state` for that, whichever is more appropriate for your situation.

`frontity.settings.js`:

```javascript
import { config } from "dotenv";

// Launch dot-env.
config();

const settings = {
  name: "my-project",
  state: {
    env: {
      myVariable: process.env.MY_VARIABLE
    }
  },
  packages: [
    // ...
  ];
}
```

`packages/my-package/src/server.js`:

```javascript
import { config } from "dotenv";

// Launch dot-env.
config();

export default {
  state: {
    theme: {
      myVariable: process.env.MY_VARIABLE,
    },
  },
};
```

Either way, the ENV variable will be serialized with the rest of the `state` and it will be sent to the client for the React hydration.

{% hint style="danger" %}
Please note that any ENV variable exposed in `state` will end up in the client. *Do not expose any secret API KEY or password.*
{% endhint %}


# WordPress requirements for Frontity

To work with Frontity you will need a **WordPress installation**. This can be hosted locally, on a web-server, or you can also use a site hosted on wordpress.com

Any standard installation should work with Frontity but just to be thorough, let's review some basic stuff that needs to be taken into account on the WordPress side so everything works smoothly.

## WordPress requirements

### Have a recent WordPress version

Frontity depends on the [WordPress REST-API](https://developer.wordpress.org/rest-api/). If you have a recent version of WordPress installed, or if you're using wordpress.com then you should be good to go.

Any WordPress site running at least [version 4.7](https://wordpress.org/support/wordpress-version/version-4-7/) (December 6, 2016) has a REST API directly available (no plugin needed)

### Have public access to the REST API

If you have a recent version of WordPress then you should have public access to the REST API of your WordPress installation.

Anyway, you can check that your WordPress REST-API is working and publicly available.

The URL of this REST API may [vary depending on the type of WordPress installation](https://docs.frontity.org/guides/setting-url-wordpress-source-data) but for a typical self-hosted WordPress installation (wp.org) this URL can be got by adding `/wp-json/` to the end of your site’s URL.

From that URL you should see a structure of data representing the content of your WordPress (something like [this](https://test.frontity.org/wp-json/wp/v2)). Don't worry, this is JSON and Frontity is very happy with this.

### Have pretty permalinks activated

Frontiy requires that the WordPress data source uses one of the pretty permalinks options, rather than the plain one, in `Settings->Permalinks`.

![](https://frontity.org/wp-content/uploads/2021/04//wordpress-permalink-setting.png)


# URLs in a Migration from WordPress to Frontity Decoupled Mode

If you are **migrating an existing WordPress site to Frontity** and you are using [**Decoupled Mode**](/architecture/decoupled-mode), you will need to change the URL of your WordPress site. You need to do this as the primary domain (i.e. the one that site visitors use) will point to the Frontity site, and the domain that points to the WordPress installation will need to be changed to the secondary domain (or subdomain).

![](https://frontity.org/wp-content/uploads/2021/05/decoupled-mode-features.png)

## The issue with URLs in this scenario

Let's take as an example a WordPress site under the domain `www.domain.com`. Let's suppose that we want to migrate this to Frontity in Decoupled Mode. We will need to make the following changes:

* `www.domain.com` will point to the Frontity server
* `wp.domain.com` will point to the WordPress server

In this scenario internal links that exist in the content when the WordPress URL is changed to `wp.domain.com` will still point to `www.domain.com`. However, if any content is added after the change then internal links will point to `wp.domain.com`. This creates a situation where internal links in the content are inconsistent, with "old" links pointing to `www.domain.com` and "new" links pointing to `wp.domain.com`.

{% hint style="info" %}
**Note that** WordPress always uses absolute links internally, rather than relative links. WordPress uses the [internal URL `Settings`](https://wordpress.org/support/article/changing-the-site-url/) to determine where the internal links should point to.
{% endhint %}

In addition, the [link processor](https://api.frontity.org/frontity-packages/collections-packages/components#the-link-processor) uses the [domain configured as the WordPress data source](/guides/setting-url-wordpress-source-data) (which will now be `wp.domain.com`) to convert links to a `<Link />` component. So if the internal links are left pointing to `www.domain.com` the link processor won't work on those links because it will only convert links pointing to `wp.domain.com`, i.e. the URL of the WordPress data source.

## Updating the URLs in WordPress

You will therefore need to change [the `WordPress Address` and the `Site Address`](https://wordpress.org/support/article/changing-the-site-url/) in the "Settings" page of the WordPress admin so they point to new URL (e.g. `wp.domain.com`).

![](https://frontity.org/wp-content/uploads/2021/05/migration-wordpress-frontity-settings.png)

Also, for the reasons stated above, any URLs in the content stored in the database also need to be updated to reflect the new domain (e.g. `wp.domain.com`). This can be done in 2 ways:

* With a WordPress plugin
* Updating the URLs manually

### Using a plugin

To change the URLs in the content stored in the database you can use a plugin such as one of the following:

* [Velvet Blues Update URLs](https://wordpress.org/plugins/velvet-blues-update-urls/)
* [Go Live Update URLs](https://en-gb.wordpress.org/plugins/go-live-update-urls/)
* [Better Search Replace](https://wordpress.org/plugins/better-search-replace/).

### Updating manually

You can also update the links manually by running the following SQL commands using either `phpMyAdmin` or an application such as [Sequel Pro](https://www.sequelpro.com/) or [Sequel Ace](https://sequel-ace.com/).

{% hint style="danger" %}
Before running the commands below ensure that you have **a backup of your database**!
{% endhint %}

```sql
UPDATE wp_options SET option_value = replace(option_value, 'https://www.domain.com', 'https://wp.domain.com') WHERE option_name = 'home' OR option_name = 'siteurl';
```

```sql
UPDATE wp_posts SET guid = replace(guid, 'https://www.domain.com', 'https://wp.domain.com');
```

```sql
UPDATE wp_posts SET post_content = replace(post_content, 'https://www.domain.com', 'https://wp.domain.com');
```


# Frontity Query Options

"Frontity Query Options" are query string parameters added to the URL that start with `frontity_`.

For example:

```
https://example.com/my_post?frontity_name=Site-name
```

Any query parameter in the URL that starts with `frontity_` is a "Frontity Query Option".

They can be used to dynamically configure certain options in the Frontity state.

> It is important to note that Frontity Query Options do not form part of the canonical link. This means that whatever is passed in the `frontity_` query parameter will not be matched by handlers or used to fetch data from WordPress. Its purpose is merely to allow dynamic configuration of Frontity.

Query string parameters that start with `frontity_` are reserved to **send special information to Frontity**, i.e. they are not related to the URL that needs to be rendered (e.g. a post or a page), but instead are used to change the Frontity configuration dynamically.

These parameters are removed from `state.frontity.initialLink` and `state.router.link` because they should not affect the content of what needs to be rendered such as a post or a page.

If Frontity Query Option parameters are present in the URL then they are added to `state.frontity.options`, and the properties are then available to any packages that need them.

> Note that the key names of parameters are camelCased when they are added to `state.frontity.options`. So, for example, the `frontity_source_auth` query string param will become `state.frontity.options.sourceAuth` once added.
>
> Only key names are transformed in this way, values remain unchanged.

Some "Frontity Query Options" are used by [`@frontity/core`](https://api.frontity.org/frontity-packages/core-package), such as:

* frontity\_name -> state.frontity.options.name: The name of the site you want to load.

> Note that the `frontity_name` setting is used only in development and only in [Frontity multisite](https://docs.frontity.org/learning-frontity/settings#multiple-sites).

However packages can also make use of them, for example:

* frontity\_source\_auth -> state.frontity.options.sourceAuth: An authentication token for the [source package](https://api.frontity.org/frontity-packages/features-packages/wp-source#state-source-auth).

{% hint style="info" %}
Currently these are the only Frontity Query Options that Frontity itself uses but it's intended that more will be added in the future. However, you can also add your own Frontity Query Options if you want to use them in your package or theme.
{% endhint %}

{% hint style="danger" %}
**Please note:** Frontity Query Options should be treated as untrusted user input and should never ever be passed as parameters to arbitrary functions.
{% endhint %}


# Redirections with Frontity

Many users store their 30x redirections in the WordPress database, e.g. via a [Redirection plugin](https://wordpress.org/plugins/redirection/). WordPress redirects a user to a new link, for example after a user renames a post and tries to access it using the "old" link. However, no such functionality exists out-of-the-box for the REST API. Since Frontity uses the REST API to retrieve content, it needs a way of handling such redirections.

Have a look at this [Demo](/guides/redirections-with-frontity#demo) for a bit more in-depth explanation.

## Settings

The redirections functionality works by making an additional request to the WordPress instance to check if a redirection exists for a particular URL. By WordPress instance, we mean the location of your WordPress installation, not the Frontity app. Normally the `state.source.url` points to that location.

The setting [`state.source.redirections`](https://api.frontity.org/frontity-packages/features-packages/wp-source#state-source-redirections) dictates under what circumstances should Frontity make that request to the check if a redirection exists.

The `state.source.redirections` accepts the following values:

#### `"no"`

Does not handle redirections at all. This is the default.

#### `"all"`

Always make an additional request to the WordPress instance to check if there exists a redirection. This means that every time you navigate to a new link, Frontity will make 2 requests: one to the REST API to try to fetch the content and another one to the WordPress instance to check if a redirection exists. Frontity will wait for both requests to finish before proceeding.

![Redirections All](https://frontity.org/wp-content/uploads/2021/04//redirections-all.png)

#### `"404"`

Only send the additional request to the WordPress instance if the original request to the REST API has returned a 404. This would happen for example if try to access a post that has been renamed.

![Redirections 404](https://frontity.org/wp-content/uploads/2021/04//redirections-404.png)

#### RegEx pattern

A string that contains a regex pattern. The string must start with `RegExp:`. This pattern will be matched against the current route and if matched, Frontity will make an additional request to the WordPress instance to check if there exists a redirection *for that route*. Note that the shorthand character classes will have to be escaped, so for example instead of `\d`, you will need to write `\\d`.

#### Array of strings

An array of strings, which can contain the "404" value as well as any number of strings starting with `"RegExp:"` which represent regular expressions. An additional request will be sent to Wordpress to check for the redirection if any of the regular expressions match the current route. If the array also contains a `"404"`, an additional request will also be made if the original request has returned a 404.

## Usage

{% hint style="warning" %}
In order for the redirections to work correctly you will need to set up CORS headers in your WordPress installation. If you are using the Redirections plugin, [it's quite simple](https://youtu.be/-ekz2JwHHmQ)
{% endhint %}

In order to use the redirections, there is no need to install any new npm package. There is a new property exposed by the `wp-source` package, [`state.source.redirections`](https://api.frontity.org/frontity-packages/features-packages/wp-source#state-source-redirections) which is used to handle the redirections. The recommended way of using it is by setting it in your `frontity.settings.js` file.

`state.source.redirections` accepts the options outlined above.

**Examples**

```javascript
// frontity.settings.js

{
  name: "@frontity/wp-source",
  state: {
    source: {
      url: "https://test.frontity.org",

      // always check if there exists a redirection.
      redirections: "all",

      // match the url `/some-post` exactly
      redirections: "/some-post/",

      // match urls like `/some-post/1`, `/some-post/2`, etc.
      redirections: "RegExp:/some-post/(\\d*)",

      // match urls like: /some-post/42, /some-otherpost/5
      redirections: "RegExp:/post-(\\w*)/(\\d*)",

      // match a combination of multiple options
      redirections: ["404", "/some-post/", "RegExp:/another-post/(\\d)"],
    },
  },
}
```

### Alternative usage

Redirections work internally by assigning a special `RedirectionData` object to `state.source.data[link]` (details below in [Technical details](https://gitbook-docs.frontity.org/guides/pages/-MY9-Gh8jvQnZd-oZTvm##Technical-details)).

A consequence of that is that [you can alternatively define redirections directly in the `state` or using a custom handler](https://community.frontity.org/t/301-redirects-stored-in-wordpress-database/3032/15).

* Single redirection populating `state.source.data` with `RedirectionData` directly:

  ```
   const state = {
     source: {
       data: {
         "/old-url/": {
           isReady: true,
           isRedirection: true,
           is301: true,
           redirectionStatus: 301,
           isExternal: false,
           location: "/new-url",
         },
       },
     },
   };
  ```
* A custom handler which assigns properties of `RedirectionData` object for the current route:

  ```
   const categoryRedirection = {
     pattern: "/category/:slug",
     priority: 5,
     func: ({ link, params }) => {
       state.source.data[link].isReady = true;
       state.source.data[link].isRedirection = true;
       state.source.data[link].is301 = true;
       state.source.data[link].redirectionStatus = 301;
       state.source.data[link].isExternal = false;
       state.source.data[link].location = `/categoria/${params.slug}`;
     },
   };
  ```

## Note on functionalities

* The redirections support not only redirecting to other pages in your WordPress site but also redirecting to external pages.&#x20;
* You can define 301, 302, 307 or 308 Redirections.
* We respect the settings of the Redirections plugin with respect to the query parameters:

![Redirections Query Parameters](https://frontity.org/wp-content/uploads/2021/04//redirections-query-parameters.png)

## Technical details

The redirections are first handled inside of `actions.source.fetch()`. If the setting for `state.source.redirections` contains an ["eager" value](https://github.com/frontity/frontity/blob/2eb98ae4e6fee1f93ac5af5c834a3add644ba7b0/packages/wp-source/src/utils.ts#L152-L186) (for example if it equals `"all"`) it is [fetched before calling the handler](https://github.com/frontity/frontity/blob/2eb98ae4e6fee1f93ac5af5c834a3add644ba7b0/packages/wp-source/src/actions.ts#L91-L100) for the current route. "Fetching a redirection" refers to making a request to the WordPress instance to check if a redirection exists for a particular URL.

If a redirection is not "eager" (for example if `state.source.redirections` is `"404"`) then we fetch the redirection only [after the request to the REST API has returned a 404](https://github.com/frontity/frontity/blob/2eb98ae4e6fee1f93ac5af5c834a3add644ba7b0/packages/wp-source/src/actions.ts#L152-L160).

The actual logic for fetching the redirection from the WordPress instance is [different on the client and server](https://github.com/frontity/frontity/blob/2eb98ae4e6fee1f93ac5af5c834a3add644ba7b0/packages/wp-source/src/utils.ts#L46-L140) because of platform differences.

In both cases, if a redirection *does* exist for a a particular route, Frontity populates `state.source.data[link]` with a `RedirectionData` object instead of a "typical" `Data` object like `PostData` or `AuthorData`. This object contains all the information about a redirection that Frontity needs in order to handle it. You can check the [type of `RedirectionData`](https://github.com/frontity/frontity/blob/2eb98ae4e6/packages/source/types/data.ts#L426-L462) to see all of its properties.

Once a `RedirectionData` object is in the state, the behavior of Frontity is different on client and server.

On the **server**, we [check the data object for the current route in the `beforeSSR()` action of `tiny-router`](https://github.com/frontity/frontity/blob/2eb98ae4e6/packages/tiny-router/src/actions.ts#L268-L298). If that object contains a redirection, Frontity will set the correct HTTP status, and redirect using `ctx.redirect(data.location)` where `data.location` contains the final URL .

On the **client**, we [listen to changes to the `state.source.data` object](https://github.com/frontity/frontity/blob/2eb98ae4e6/packages/tiny-router/src/actions.ts#L156-L177) and if the `data` object for current route contains a redirection, Frontity calls `actions.router.set(data.location)` where `data.location` contains the final URL.

The above flow looks something like:

![Redirections Schema](https://frontity.org/wp-content/uploads/2021/04//redirections-schema.jpeg)

## Demo

This short video demonstrates the usage of the Redirections feature in Frontity.

{% embed url="<https://www.youtube.com/watch?v=_ZNgyXJxeGM>" %}


# Understanding a Frontity project

Guide to help you understand what is involved in a Frontity project

## What you get in a new Frontity project.

If you have followed our [quick start guide](/getting-started/quick-start-guide) you probably have already a new Frontity project. If not, run `npx frontity create <project-name>` and you'll get a project with the same structure as the one explained in this guide.

So, the important pieces that you get, once a project is created, are:

* A `package.json` file where the dependencies needed for your app to work are declared.
* A `frontity.settings.js` file where the basic setup for your app is already populated.
* A `packages` folder with `mars-theme` installed inside.

### The `package.json` file

The basic dependencies we'll need for our app to work are:

* **`frontity`** : this is the main package, where we can find all the methods we might need to use during development. It's also where the CLI lives.
* **`@frontity/core`** : here is where the magic happens. Core takes care of all the bundling, rendering, merging, transpiling, serving, etc. We don't need to access to it in order to develop a Frontity app.
* **`@frontity/wp-source`** : this package is the one that connects to the WordPress REST API of your site and fetches all the data needed on your Frontity theme.
* **`@frontity/tiny-router`** : this is a small package that handles `window.history` and helps us with the routing on `mars-theme`.
* **`@frontity/mars-theme`** : this is our starter theme, where we build our site with React.

As you can see, our `mars-theme` dependency has no version but a path. This is how we need to add our custom packages (those we are developing inside the app) to our `package.json` so they will be treated as if they were living in `node_modules`.

### The `frontity.settings.js` file

In this file we define our project settings. We also define the extensions needed to successfully run a Frontity app. You can learn more about this file in the [Settings reference](https://docs.frontity.org/learning-frontity/settings).

### The `packages` folder

In this folder is where we create all the custom extensions we want to develop for our site. Usually it will be a custom theme. In this case, the one installed by default is our `mars-theme`. Any changes done in these extensions during development will refresh our site automatically.

## How does everything work together

When starting `frontity`, all the packages defined in `frontity.settings.js` are imported by `@frontity/file-settings` and the settings and exports from each package are merged by `@frontity/core` into a single `store` where you can access the `state` and `actions` of the different packages during development using `@frontity/connect` (our state manager).

{% hint style="info" %}
Still have questions? Ask [the community](https://community.frontity.org/)! We are here to help 😊
{% endhint %}


# Add a new Frontity package or theme to your project

{% hint style="info" %}
In Frontity *themes* are just any other type of package, so the info explained in this guide can be applied to when you want to use an alternative theme in your project
{% endhint %}

During the development of your project, you may want to install new Frontity packages, or even change the ones you are using (for example if you want to use a different theme or a different analytics service). In order to do this, you'll need to:

1. Install the Frontity package.
2. Add it to `frontity.settings.js`.

{% hint style="info" %}
Please note that this process is only necessary for [Frontity packages](https://api.frontity.org/frontity-packages). If you want to install an npm package you can use the normal `npm install some-package` procedure.
{% endhint %}

## 1. Install the Frontity package

At this point, you need to differentiate between the external packages (which aren't meant to be modified) and the local packages (the ones you want to change at your will), because its installation will be slightly different. If you want to understand better how external and local packages work you can check its [docs page](/learning-frontity/packages).

### External packages

{% hint style="info" %}
This is the typical way of using [Features Packages](https://api.frontity.org/frontity-packages/features-packages)
{% endhint %}

These packages will be treated like any `npm` package and stored in `node_modules` folder, where all your dependencies are installed. In order to install a package as external you just have to run this command in the root of your project:

```
npm install new-frontity-package
```

It will be automatically added to your `node_modules` folder and your `package.json` file.

### Local packages

{% hint style="info" %}
This is the typical way of using Frontity [Themes](https://api.frontity.org/frontity-themes)
{% endhint %}

The process to install a local package is pretty similar, but you'll have to make minor modifications.

1. You need to **install the package** as an external one by running `npm install new-frontity-package`&#x20;
2. It will be installed inside the `node_modules` folder of your project, so you'll need to **look for the package and move it to the folder `packages`** inside your Frontity project.
3. Next step would be to **change your `package.json`**. You'll have your new package inside the dependencies of your project, pointing to its latest version. As we are going to use it as a `local` package, we have to point it to its proper folder.

```javascript
{
  "name": "frontity-project",
  ...
  "dependencies": {
    ...
    "another-frontity-theme": "./packages/another-frontity-theme",
    //before it would be something like "another-frontity-theme": "^1.0.0"
    ...
  }
}
```

1. Once changed, run `npm install` at the root of your project and it will work as `local` package.

{% hint style="info" %}
We are planning to release a new command, that will take care of all these steps.
{% endhint %}

## 2. Add it to \`frontity.settings.js\`

Once installed, the process it's the same for both external and local packages.

You have to include it in your `frontity.settings.js`, inside the `packages` array to make it work. Remember to check if any settings are needed and include them as well (You can check that at each specific [Frontity Package](https://api.frontity.org/frontity-packages) or [Frontity Theme](https://api.frontity.org/frontity-themes)).

```javascript
const settings = {
  ...
  "packages": [
    ...
    //If the package has no settings
    "new-frontity-package",

    //If you want to add settings to your package
    {
      "name": "new-frontity-package",
      //Add your settings here
    },
    ...  
  ]
};

export default settings;
```

And that's all, your package is installed and working now.

{% hint style="info" %}
Note that if you are changing your theme or any other package, you may want to remove the old one in your `package.json` and in your `frontity.settings.js`
{% endhint %}


# How to share your Frontity project

When you create a Frontity project most of the times you'll end up creating a custom theme:

* Because you need some specific design and features for your project
* Because you directly want to create a theme that can be reused by others (like [@frontity/mars-theme](https://www.npmjs.com/package/@frontity/mars-theme) or [@frontity/twentytwenty-theme](https://www.npmjs.com/package/@frontity/twentytwenty-theme))

Whatever the case is, you may want the community:

* To be able to check the code of your theme
* To be able to install it locally so it can be debugged → this will help the community to help you with any issue you may have with your project/theme
* To be able to install it as an npm package (eventually) so it can be easily reused in some other projects

Here you have a few things to consider to ease contributions and support from the community to your theme

## A Frontity *theme* project structure

In Frontity, *themes* are packages that can be published in npm so they can be installed and used in any other Frontity project

{% hint style="info" %}
You can find all the Frontity themes looking for the tag [`frontity-theme`](https://www.npmjs.com/search?q=keywords:frontity-theme) at npm
{% endhint %}

The suggested structure for developing new themes that works with Frontity is the following one

```
/my-frontity-project
|__ frontity.settings.js
|__ package.json
|__ /node_modules
|__ /packages
    |__ /awesome-theme
    |__ /my-custom-extension-1
    |__ /my-custom-extension-2
```

{% hint style="info" %}
***This is the structure we recommend you to upload to your remote git repository*** (Github, Bitbucket or any other)

Examples:

* <https://github.com/chakra-ui/frontity-chakra-ui-theme>
* <https://github.com/imranhsayed/frontity-twentynineteen>
* <https://github.com/alexadark/frontity-starter-theme>
* <https://github.com/igmoweb/igmoweb.com>
* <https://github.com/goiblas/personal-blog>
  {% endhint %}

In this structure, the theme you're developing is a local dependency of the main `package.json`

```
"dependencies": {
    "awesome-theme": "file:packages/awesome-theme"
  }
```

{% hint style="info" %}
This type of dependency is automatically defined if you create the package (theme) w/ the Frontity command `npx frontity create-package awesome-theme`\
» Read more about [`frontity create-package`](/guides/how-to-share-a-frontity-project)
{% endhint %}

This structure implies having a main Frontity project (root `package.json`) and some packages (each one with its own `package.json`) under the `packages` folder

```
/my-frontity-project
...
|__ package.json
...
|__ /packages
    |__ /awesome-theme
    |__ /my-custom-extension-1
    |__ /my-custom-extension-2
```

So, to create a custom theme project we recommend you to:

1. Create a Frontity project → `npx frontity create awesome-theme-project`
2. Create a Frontity package (your theme) → `npx frontity create-package awesome-theme`

### [The Project](https://docs.frontity.org/learning-frontity/project)

These files in the root represents the Frontity project that can be launched and that will allow to see the *theme* (or any other package) in action

In the *root folder* you'll find the following:

#### `frontity.setting.js`

A [`frontity.setting.js`](https://docs.frontity.org/learning-frontity/project#the-frontity-setting-js-file) file containing the settings for your project (among other settings you'll usually define the use of this theme)

For example:

```
...
"packages": [
    {
      "name": "awesome-theme"
    },
...
```

#### `node_modules`

A [`/node_modules/`](https://docs.frontity.org/learning-frontity/project#the-node_modules-folder) folder, where the dependencies of the project are installed

#### `packages`

A [`packages`](https://docs.frontity.org/learning-frontity/project#the-packages-folder) folder where your local packages live

#### `package.json`

And a [`package.json`](https://docs.frontity.org/learning-frontity/project#the-package-json-file) with the configuration & dependencies for the Frontity project.

This `package.json` is used when you publish a package in npm, but this Frontity project is not meant to be published

{% hint style="info" %}
Notice the `"private": true` preventing this package (the main Frontity project defined in the root) being published
{% endhint %}

### The Theme

With this structure you can develop your theme as a package inside the `packages` folder.

Each one of these *packages* will have its own `package.json` and these packages are the ones meant to be published (`npm publish`)

{% hint style="info" %}
In Frontity you can create a new package by doing `npx frontity create-package <my package name>` (from the root of the Frontity project)\
» Read more about [`frontity create-package`](/guides/how-to-share-a-frontity-project)
{% endhint %}

### Why this structure?

This structure allows to:

* Launch the project using the theme locally
* Publish the theme independently&#x20;

So any developer can clone this project, launch the Frontity project locally, have a look at how the theme looks like & behave and make contributions (pull requests) to your repository (that can be eventually merged into the main repository).

And also, the owner of the theme still can publish those new updates independently (from the theme folder, `packages/awesome-theme` in this case)

## Sharing your GitHub repository on CodeSandbox

GitHub repositories containing Frontity projects with the structure explained above, can be directly opened in CodeSandbox by using one of the following URL structures:

```
https://githubbox.com/<%GITHUB_ACCOUNT%>/<%FRONTITY_PROJECT_REPOSITORY%>
https://codesandbox.io/s/github/<%GITHUB_ACCOUNT%>/<%FRONTITY_PROJECT_REPOSITORY%>
```

For example this repo <https://github.com/frontity-demos/demo-custom-homepage-categories> can be opened directly in CodeSandbox with links like:

* <https://codesandbox.io/s/github/frontity-demos/demo-custom-homepage-categories>
* <https://githubbox.com/frontity-demos/demo-custom-homepage-categories>

## Example: Frontity Chakra Theme

Let's take [**Frontity Chakra Theme**](https://github.com/chakra-ui/frontity-chakra-ui-theme) as an example of a Frontity theme available:

* As [an npm package](https://www.npmjs.com/package/frontity-chakra-theme) ready to be installed and used as a theme in any Frontity project&#x20;
* In a [GitHub repository](https://github.com/chakra-ui/frontity-chakra-ui-theme) ready to be cloned and launched locallly, and also ready to accept contributions from the community via [Pull Requests](https://opensource.guide/how-to-contribute/#opening-a-pull-request)

### Clone and launch it locally

Once we [clone the theme](https://help.github.com/en/github/creating-cloning-and-archiving-repositories/cloning-a-repository) we can see the project follows the structure of a typical Frontity project

```
/frontity-chakra-ui-theme
|__ frontity.settings.js
|__ package.json
...
|__ /packages
    |__ /frontity-chakra-theme
```

From the root of the project we can do

```
npm install
```

This command will install the dependencies of the Frontity project and the dependencies of its dependencies, just as any other npm package

So, as Frontity Chakra Theme is also one of the dependencies ([a local dependency](https://www.viget.com/articles/how-to-use-local-unpublished-node-packages-as-project-dependencies/)) is:

```
"dependencies": {
   ...
    "frontity-chakra-theme": "./packages/frontity-chakra-theme"
  }
```

All needed dependencies (the ones defined for the Frontity project and the ones defined for the theme) are installed

{% hint style="info" %}
[Read more about](https://docs.npmjs.com/cli/install) `npm install <folder>`
{% endhint %}

Once we have all the dependencies installed you can do (from the root)

```
npx frontity dev
```

This will launch the Frontity project using this theme

### Publish the theme (as npm package)

As we can see `frontity-chakra-theme` is published as [an npm package](https://www.npmjs.com/package/frontity-chakra-theme)

```
> npm search frontity-chakra-theme
NAME                      | DESCRIPTION          | AUTHOR          | DATE       | VERSION  | KEYWORDS
frontity-chakra-theme     | A frontity theme…    | =segunadebayo   | 2020-01-28 | 0.0.2    | wordpress frontity frontity-theme frontity
```

How did [@segunadebayo](https://github.com/segunadebayo) published this theme once he finished it? Just by doing:

```
cd packages/frontity-chakra-theme
npm publish
```

{% hint style="info" %}
Take into account that there cannot be two packages with the same name (property `name` in your `package.json`) so if you try to publish a package that is already published you will get an error
{% endhint %}


# Understanding Mars Theme

Guide to understand how our starter theme works.

Mars theme is our starter theme and is installed by default on `frontity create`. Here we'll explain how [`@frontity/mars-theme`](https://github.com/frontity/frontity/tree/dev/packages/mars-theme) works.

> If you yet don't understand the structure of a Frontity project, please read our guide [Understanding a Frontity project](/guides/understanding-mars-theme).

{% hint style="info" %}

{% endhint %}

Have a look at this Frontity Talk where we talk about the `mars-theme`:

* 📺 [Frontity Talks 2020-04 - mars-theme \[27:52\]](https://www.youtube.com/watch?v=e6n1j4gwFjQ\&t=1672s)

## Frontity Utilities

Utilities are those libraries that are part of the Frontity core and need to be exposed to us in order to successfully develop a theme that integrates completely with Frontity. All those utilities are exposed in the`frontity` package.

For example, our state manager `@frontity/connect` exposes a utility called `connect` to wrap our React components so we can access the Frontity store from them. To avoid us the need to remember lots of packages and dependencies, we can import `connect` and other libraries like this:

```jsx
import { connect, styled } from "frontity";

const HelloWorld = () => <Container>Hello World!</Container>;

export default connect(HelloWorld);

const Container = styled.div`
  background: blue;
  color: white;
`;
```

As you can see in the example above, we are accessing also `styled` from `frontity`. In this case `frontity` is just exposing the API of `@emotion/styled`, and it does this with other libraries like `react-helmet`, so you get everything that you'd usually need in just one line.

## Exports

The extension itself can be an object or a function that returns that object. You can see the object structure explained in the following code, along with what we are exporting in `mars-theme`:

```typescript
import Theme from "./components/theme";

const marsTheme = {
  // The name of the extension.
  name: "@frontity/mars-theme",
  // The React components that will be rendered.
  roots: {
    theme: Theme,
  },
  // The default state that the extension needs to create in order to work.
  state: {
    theme: {
      menu: [],
      featured: {
        showOnList: false,
        showOnPost: false,
      },
    },
  },
  // The actions that the extension needs to create in order to work.
  // In our case, `mars-theme` doesn't export any actions.
  actions: {},
  // The libraries that the extension needs to create in order to work.
  // In our case, `mars-theme` doesn't export any actions.
  libraries: {},
};

export default marsTheme;
```

In each part of the exported object, what the extension defines needs to be inside its `namespace`. In our case, all the things we are defining are inside the `theme` namespace, but if our theme implemented, for example, a comments solution, that state, actions, etc., should be defined inside the `comments` namespace. So, in the case of `roots`, it would be something like:

```typescript
import Theme from './components/theme';
import Comments from './components/comments';

const extension = {
  ...
  roots: {
    theme: Theme,
    comments: Comments,
  },
  ...
};
```

## Building the theme

There are some steps that we need to go through in order to have our theme working:

### SSR populated

First of all, we want our server-side rendering to be equal to our client-side rendering to not harm the UX and SEO. In order to do this, we are going to use an action called `beforeSSR`. This action will be run by `@frontity/core` before the server-side render is generated by React and it's the best place to request the data we need from our WP:

We are doing this in our `src/index.js` file:

```javascript
const marsTheme = {
  name: "@frontity/mars-theme",
  roots: { ... },
  state: { ... },
  actions: {
    theme: {
      beforeSSR: async ({ state, actions }) => {
        // We fetch the initial link.
        await actions.source.fetch(state.router.link);
        // NOTE: This is not needed if autoFetch is activated in your router.
      }
    }
  }
};
```

Now that we have the data we need to render our app, we can start writing some React. All the components described below can be found inside `src/components`.

### Theme component

Our main React component will be `Theme`, where we are deciding what kind of view to render, and in order for that component to access the store, we need to wrap it with the `connect` function. Once it's wrapped, we can access `state` and `actions` directly from the props. In this case, we are using `state.source.get()` to retrieve info about what kind of content should be rendered in the current path. If it happens to be an archive, we will render the `<List />` component, if a post type, the `<Post />` and if for some reason `wp-source` couldn't retrieve the data from our WP, we will render a 404 page.

Here you have the code of `Theme` with some comments:

{% code title="index.js" %}

```jsx
import React from "react";
import {
  // Modules from `@emotion/core` and `@emotion/styled`.
  Global,
  css,
  styled,
  // Module from `@frontity/connect`.
  connect,
  // Alias for `Helmet` from `react-helmet`.
  Head
} from "frontity";
import Header from "./header";
import List from "./list";
import Post from "./post";
import Page404 from "./page404.js";

const Theme = ({ state }) => (
  <>
    // Adding some elements to <head>
    // with `react-helmet`.
    <Head>
      <title>{state.frontity.title}</title>
      <html lang="en" />
    </Head>
    // Adding global styles to our app.
    <Global styles={globalStyles} />
    // Just rendering the Header component.
    <HeadContainer>
      <Header />
    </HeadContainer>
    <Body>
      // Here is where we use our `state.source.get()` to decide
      // what component we'll render.
      {state.source.get(state.router.link).isArchive && <List />}
      {state.source.get(state.router.link).isPostType && <Post />}
      {state.source.get(state.router.link).is404 && <Page404 />}
    </Body>
  </>
);

export default connect(Theme);
```

{% endcode %}

Between the `Post` component and the `List` component there are a bunch of different things going on here. I'll start with `List`.

### List component

It is exported from `list/index.js`. There, we are using `loadable` from `frontity` (which is actually an alias for the `default` export of `@loadable/components`) to split the code of our `List` component, so it won't be loaded if a user access directly to a `Post` view, and instead the code will be requested when the user clicks on a list view. This is helpful to reduce the loading times and times to interactive of our site. The less code we have, the less time the browser spends evaluating it.

{% code title="list/index.js" %}

```javascript
import { loadable } from "frontity";

// Codesplit the list component so it's not included if the users
// load a post directly.
export default loadable(() => import("./list"));
```

{% endcode %}

Now, our `List` component is the responsible to render a list of posts, and for that it needs to know what posts to render. We are using `state.source.get(link)` and its `items` field.

{% code title="list/list.js" %}

```jsx
const List = ({ state }) => {
  // Get the data of the current list.
  const data = state.source.get(state.router.link);

  return (
    <Container>
      {/* If the list is a taxonomy, we render a title. */}
      {data.isTaxonomy && (
        <Header>
          {data.taxonomy}: {state.source[data.taxonomy][data.id].name}
        </Header>
      )}

      {/* If the list is an author, we render a title. */}
      {data.isAuthor && (
        <Header>Author: {state.source.author[data.id].name}</Header>
      )}

      {/* Iterate over the items of the list. */}
      {data.items.map(({ type, id }) => {
        const item = state.source[type][id];
        // Render one Item component for each one.
        return <Item key={item.id} item={item} />;
      })}
      <Pagination />
    </Container>
  );
};
```

{% endcode %}

The last detail we are going to explain is how we are doing pagination on `List`.

We are getting the total of pages for that list from `state.source.get(link)` and we are checking if we are either in the first one, the last one, or in the middle. Using the React hook `useEffect` we are prefetching the next page when the component mounts, so in the case the user goes there, he doesn't have to wait for the response from the WP REST API.

Depending on the page we are at the moment, we render different links to travel through the list. For that we are using our own `Link` component, which accepts the same parameters as `actions.source.fetch()` or `actions.router.set()`.

{% code title="list/pagination.js" %}

```javascript
const Pagination = ({ state, actions, libraries }) => {
  const { totalPages } = state.source.get(state.router.link);
  const { path, page, query } = libraries.source.parse(state.router.link);

  const isThereNextPage = page < totalPages;
  const isTherePreviousPage = page > 1;

  const nextPageLink = libraries.source.stringify({
    path,
    page: page + 1,
    query,
  });

  const prevPageLink = libraries.source.stringify({
    path,
    page: page - 1,
    query,
  });

  useEffect(() => {
    // Fetch the next page if it hasn't been fetched yet.
    if (isThereNextPage) actions.source.fetch(nextPageLink);
  }, []);

  return (
    <div>
      {isThereNextPage && (
        <Link link={nextPageLink}>
          <em>← Older posts</em>
        </Link>
      )}
      {isTherePreviousPage && isThereNextPage && " - "}
      {isTherePreviousPage && (
        <Link link={prevPageLink}>
          <em>Newer posts →</em>
        </Link>
      )}
    </div>
  );
};
```

{% endcode %}

### Post component

There is something new here, that we haven't done on `List`. We are doing a preload of the `List` component (as it is a dynamic component and we don't have that code yet). Once we have our site rendered and working, we preload the code for `List`, so the user won't need to wait for it later if she decides to visit a list of posts.

{% code title="post.js" %}

```javascript
import List from './list';

const Post = ({ state, actions }) => {
  const data = state.source.get(state.router.link);
  const post = state.source[data.type][data.id];
  // Get the author.
  const author = state.source.author[post.author];
  const date = new Date(post.date);

  useEffect(() => {
    actions.source.fetch("/");
    // Here is where we are preloading the List component.
    // This will run only on mount.
    List.preload();
  }, []);

  return data.isReady ? (
    <Container>
      { ... }
    </Container>
  ) : null;
};
```

{% endcode %}

### Defining the theme state

The last thing that might need to be explained is how we define `state` for our extension in order to use it within React and be able to set it with a `frontity.settings` file in a Frontity project.

In `mars-theme` we are defining the following `state`:

```javascript
// src/html/index.js

const marsTheme = {
  ...,
  state: {
    theme: {
      // This field will be used in our Nav bar.
      // Here we are defining the default value.
      menu: [],
      featured: {
        showOnList: false,
        showOnPost: false
      }
    }
  }
};
```

And we are using it as shown below:

{% code title="nav.js" %}

```jsx
const Nav = ({ state }) => (
  <Container>
    {state.theme.menu.map(([name, link]) => (
      <Item key={name} isSelected={state.router.link === link}>
        <Link link={link}>{name}</Link>
      </Item>
    ))}
  </Container>
);
```

{% endcode %}

And when we create a new Frontity project where our theme is installed, that state can be changed in `frontity.settings.js`:

```javascript
const settings = {
  ...,
  packages: [
    ...,
    {
      name: "@frontity/mars-theme",
      state: {
        theme: {
          // Here is where the owner of the project can
          // set the values of the `mars-theme` state.
          ...,
          menu: [
            ["Home", "/"],
            ["Nature", "/category/nature/"],
            ["Travel", "/category/travel/"],
            ["Japan", "/tag/japan/"],
            ["About Us", "/about-us/"]
          ],
        }
      }
    }
  ]
};
```

{% hint style="info" %}
Still have questions? Ask [the community](https://community.frontity.org/)! We are here to help 😊
{% endhint %}


# Working with processors

## Table of Contents

* [What is a processor?](/guides/using-processors#what-is-a-processor)
* [Configure Frontity to use processors](/guides/using-processors#configure-frontity-to-use-processors)
* [How to use processors](/guides/using-processors#how-to-use-processors)
* [An Example](/guides/using-processors#an-example)

## What is a processor?

A [processor](https://api.frontity.org/frontity-packages/features-packages/html2react#processors) is a JavaScript object used by the `<html2react>` package that, among other things, contains a function that is executed if a certain test condition evaluates as true. The test condition is used to match elements (or nodes) in the HTML markup of the content. The *processor* function will in some way process or alter the markup of that element and return either the modified markup or even something else in it's place.

A processor is a JavaScript object with the following defined properties:

* name
* priority
* test
* processor

The values of `test` and `processor` are functions.

In the case of `test` the function simply returns a boolean value depending on whether a condition is matched. The condition checks against each node in the DOM tree. Normally it will test whether a node has a particular HTML tag or a particular class, or other property.

In this example the function returns `true` if the received node (i.e. an HTML element) is an `<img>` tag. For all other elements in the DOM tree it will return `false`.

```jsx
test: ({ node }) => node.component === "img";
```

{% hint style="info" %}
A node here is an HTML element represented in a JavaScript object. So for example, this HTML:

```markup
<div class="wp-block-group jsforwp">
  <h4>Heading</h4>
  <p>Paragraph</p>
</div>
```

would be represented in JavaScript as follows:

```javascript
{
 "type": "element",
 "component": "div",
 "props": { "className": "wp-block-group jsforwp" },
 "children": [
   { /* heading-object ... */ },
   { /* paragraph-object ... */ }
 ]
}
```

{% endhint %}

The `processor` property is a function that in some way "processes" the received node (remember that a node is a JavaScript object representing an HTML element). It can return a modified version of the element or something entirely different, such as a React compontent. This returned value will replace the original element in the DOM tree.

The execution of the `processor` function is dependent on the value returned by the `test` function. The `processor` function will only be executed if the `test` function returns `true`, therefore the `processor` function will only operate on nodes that match the `test` condition.

So, in the example above the `processor` function will only be executed if the element being tested by the `test` function is an `<img>`, and it will then *process* that element in a defined way.

## Configure Frontity to use processors

Frontity provides the [`@frontity/html2react`](https://api.frontity.org/frontity-packages/features-packages/html2react) as the Frontity-way of converting HTML to React

The main advantage of using the `Html2React` component (an improved version of React's [`dangerouslySetInnerHTML`](https://reactjs.org/docs/dom-elements.html#dangerouslysetinnerhtml)) provided by the [`@frontity/html2react`](https://api.frontity.org/frontity-packages/features-packages/html2react) package is that you can add processors to parse all the HTML rendered by this component

So, in order to use a processor you need to take these steps in your Frontity project:

{% hint style="info" %}
Note that if you are using an existing theme such as `mars-theme` or `twentytwenty-theme` then the `html2react` package is already installed and you don't need to follow these steps.
{% endhint %}

1. Install the `html2react` package into your theme

```bash
    npm i @frontity/html2react
```

1. Add `@frontity/html2react` to the `packages` array in `frontity.settings.js`

```javascript
packages: [
  // ...
  "@frontity/html2react",
];
```

1. In the component that you wish to use it get `html2react` from the `libraries` object, which must be passed via props to the component connected via `connect`.

```javascript
const MyComponent = ({ libraries }) => {
  const Html2React = libraries.html2react.Component;
  // ...
};
export default connect(MyComponent);
```

1. Use it in that component where you might otherwise use [`dangerouslySetInnerHTML`](https://reactjs.org/docs/dom-elements.html#dangerouslysetinnerhtml), passing it an `html` prop with the content that you wish to be rendered - this will usually be `post.content.rendered`.

```jsx
<Html2React html={post.content.rendered} />
```

You can see an example of it's use in the [`post.js` file in `mars-theme`](https://github.com/frontity/frontity/blob/dev/packages/mars-theme/src/components/post.js).

For more info please see [the documentation for the `html2react` package](https://api.frontity.org/frontity-packages/features-packages/html2react).

With those steps accomplished your project now has the ability to use processors.

## How to use processors

Whenever you use the `html2react` component to render the HTML for the post/page content the `test` function will be evaluated for each element in the DOM tree and the `processor` function will execute and *process* that element if the test on that node passes, i.e. returns `true`.

You add processors in the array at `libraries.html2react.processors` in the theme's `index.js`.

{% hint style="info" %}
Some processors, such as `image`, `iframe`, and `link`, are included with Frontity, and if you are using a ready-made theme such as `@frontity/mars-theme` or `@frontity/twentytwenty-theme` then they will already be added for you.
{% endhint %}

```javascript
libraries: {
    html2react: {
      processors: [image, iframe, link],
    },
```

You can also [define your own processor](https://api.frontity.org/frontity-packages/features-packages/html2react#creating-your-own-processors) and add it to this array.

As previously stated, a processor is a function that runs at render time when the HTML is parsed by the `html2react` component and a specific condition, as defined by the `test` function, is met. The condition is specified by a pattern, such as a specific element type which has a specific class. For example:

```jsx
test: ({ node }) =>
  node.component === "div" &&
  node.props?.className?.split(" ").includes("some-class");
```

Then in place of the element that meets this condition the processor returns either a processed version of it (hence the name "processor") or even something else entirely, such as a React component.

Both of the functions, i.e. the `processor` and the `test`, receive the node (i.e. a JavaScript object representing an HTML element) as a prop. They also receive the other properties of the Frontity object, i.e. `root`, `state` and `libraries`.

## An Example

In this section we will look at an example that demonstrates how you might implement a processor.

This example shows how to process an HTML element that might be found in the content from a WordPress site. In this example we will show you how to replace a `<blockquote>` element with a React component.

{% hint style="info" %}
The full code for this example can be found in [this repository](https://github.com/frontity-demos/frontity-examples/tree/master/processor-blockquote).
{% endhint %}

We first define our processor, to be named "quote", in a file `./processors/quote.js`. This file also includes the React component `<Quote>` that will replace any `<blockquote>` element that also has the class `wp-block-quote`. However, a more complex example might import this from a separate file.

```jsx
import React from "react";

const Quote = ({ quote, author }) => {
  console.log("Quote");
  console.log({ quote, author });
  return (
    <div style={{ background: "red", color: "white", padding: "10px" }}>
      <h3>{quote}</h3>
      <h5>{author}</h5>
    </div>
  );
};

const quote = {
  name: "quote",
  priority: 20,
  test: ({ component, props }) =>
    component === "blockquote" && props?.className === "wp-block-quote",
  processor: ({ node }) => {
    const quote = node.children[0].children[0].content;
    const author = node.children[1].children[0].children[0].content;
    return {
      component: Quote,
      props: { quote, author },
    };
  },
};

export default quote;
```

The `processor` function extracts certain sub-parts of the `<blockquote>` element and passes them as props to the `<Quote>` component. The `processor` function also returns the HTML returned by the `<Quote>` component.

In the final line the `quote` processor is exported.

The `quote` processor is then imported into our theme's `index.js` file:

```jsx
import quote from "./processors/quote";
```

And then included in the array of processors:

```jsx
libraries: {
    html2react: {
      processors: [image, iframe, quote],
    },
  },
```

Now, in any component that uses the `<Html2React>` component to render the content, as follows:

```jsx
<Html2React html={post.content.rendered} />
```

any element of this type:

```markup
<blockquote class="wp-block-quote">
  <!-- child elements -->
</blockquote>
```

will be processed.

Another, more elaborate, example that illustrates the use of a processor can be found [in the guide on processing page builder content](/guides/processing-page-builder-content#gutenberg).

{% hint style="info" %}
**Further information**

Documentation on the `html2react` component can be found [here](https://api.frontity.org/frontity-packages/features-packages/html2react).

More information about processors can be found [here](https://api.frontity.org/frontity-packages/features-packages/html2react#processors).

[The repository for the Frontity.org site](https://github.com/frontity/frontity.org/tree/dev/packages/frontity-org-theme) contains a [large number of examples of processors](https://github.com/frontity/frontity.org/tree/dev/packages/frontity-org-theme/src/processors) that you can examine both for ideas and for details of technical implementation in specific cases.

There is also a discussion about processors in [a video in the Frontity Talks series](https://www.youtube.com/watch?v=qOfENWKR7EE\&list=PLC9teX20GdrTBeOzSwE-bFW-MbBEUwowS\&index=10\&t=1272s).
{% endhint %}


# How to process page-builder content in Frontity

## Table of Contents

* [Introduction](#introduction)
* [How do page builders work](#how-do-page-builders-work)
* [The problem with page builders](#the-problem-with-page-builders)
* [What can we do to solve the problem](#what-can-we-do-to-solve-the-problem)
* [Examples](#examples)
  * [Gutenberg](#gutenberg)
    * [Processing Gutenberg content](#processing-gutenberg-content)
    * [Gutenberg stylesheets](#gutenberg-stylesheets)
  * [Elementor](#elementor)
    * [Processing Elementor content](#processing-elementor-content)
    * [Elementor stylesheets](#elementor-stylesheets)
    * [Elementor classes](#elementor-classes)

## Introduction

Page builders are becoming increasingly popular with content creators and content editors. They allow people who are not developers, namely content creators and editors, to work in a visual way and to lay out their content and style it with a WYSIWYG interface.

Page builders can either be page building themes such as [Divi](https://www.elegantthemes.com/gallery/divi/) and [Total](https://total.wpexplorer.com/), or plugins such as [Elementor](https://elementor.com/), [WP Bakery](https://wpbakery.com/), and [Beaver Builder](https://www.wpbeaverbuilder.com/).

In addition [Gutenberg](https://wordpress.org/gutenberg/), the new block editor for WordPress that has replaced the traditional TinyMCE based editor, also presents a WYSIWYG style interface and offers advantages similar to those offered by the more established page-builder themes and plugins. Gutenberg is undoubtedly the future of WordPress, and especially so with the forthcoming [Full Site Editing feature](https://make.wordpress.org/design/handbook/focuses/full-site-editing/) promised in the WordPress pipeline.

Whichever type of page builder is opted for, whether theme, plugin, or Gutenberg, it can be used for both posts and pages, and even custom post types if they have been [configured with the necessary support](https://www.cloudways.com/blog/gutenberg-wordpress-custom-post-type/).

## How do page builders work

As already indicated, page builders present the content creator with a WYSIWYG visual interface such that the content creator or editor can layout and style their content with the assurance that what they see while they are editing the page or post will be precisely what the visitor to the site will see. This means that even technically unskilled people can enjoy a great deal of creative freedom when creating their pages or posts.

The page builder will then generate HTML which is stored in the `post_content` field of the `wp_posts` table in the database. Enough styling information is included in the HTML, in the form of classes or inline styles, to allow the page or post to be rendered in the browser accurately simulating the appearance as it was in the editor.

{% hint style="info" %}
Virtually all page builders will structure the post/page using the *three C's*, which are Container, Column, and Content.

Top level elements are *Containers*. These will variously be called "rows" or "sections" depending on the page builder you are using. Whatever they're called in your particular page builder they divide the page/post up into distinct areas and are stacked vertically.

Each Container will have one or more *Columns*. These are arrayed horizontally - at least in large viewports on devices with large screens, but on devices with small screens or if the viewport is narrow then these could be arrayed vertically.

*Content*, i.e. what is visually seen on the screen (such as headings, paragraphs, and images), is then presented within a Column.

Whichever page builder you are using, you will find that this structure is common and can be seen reflected in the final HTML markup.
{% endhint %}

Usually the page builder will have one or more generic style sheets which define styles for the classes added by the page builder. Some of these style sheets are static and exist at the time that the page builder is installed in WordPress, and some of them may be dynamically generated for a particular site, or even for a particular page/post, as the content is created.

These style sheets need to be copied across to your Frontity project and added using the [`<Global />` component](https://api.frontity.org/frontity-packages/core-package/frontity#global).

{% hint style="info" %}
A cautionary note that should be borne in mind is that some page builders, such as Divi and WP Bakery, populate the content with a large number of shortcodes. Ideally these should result in rendered HTML appearing in the `content.rendered` property delivered by the REST API, but unfortunately some of these shortcodes can appear verbatim in the content that comes from the REST API.
{% endhint %}

## The problem with page builders

Ideally we want to have the performance, and other, benefits of a decoupled frontend for our WordPress sites, yet at the same time retain the WYSIWYG content editing experience that page builders do so well.

However, by using a decoupled frontend (such as Frontity) we lose the tight integration that exists between a page builder and WordPress, and so the appearance of the page or post as it appears in the page builder's editor, and also when viewed using the WordPress theme, is not as accurately reproduced by Frontity. At least not without some additional work on the developer's part.

## What can we do to solve the problem

There are a number of approaches that we as developers can take in order to solve the problem of pages and posts created with a page builder not appearing as intended in Frontity.

The most straightforward approach would be to create the Frontity theme to reproduce the appearance of the pages/posts built with a page builder. This approach would require agreement up-front between content creators, designers, and developers and could restrict the creative freedom of content creators and designers as they must develop the pages and posts to work within the predefined constraints of the Frontity theme. That said, this approach could work for small or stylistically simple sites.

A second approach would be to copy the style sheets that the page builder uses across to the Frontity site and import them into the project and use them with the [`<Global />` component](https://api.frontity.org/frontity-packages/core-package/frontity#global). In most cases this should result in a fairly accurate rendering of the pages or posts in Frontity. However, the benefits of CSS in JS are lost with this approach and adding several style sheets to the project using the `<Global />` component will potentially result in reduced performance of the site.

In theory it's possible to reproduce the page builders' style sheets in CSS in JS but this would be onerously difficult and time-consuming.

Another approach is to use html2react processors that detect matching elements in the HTML and "process" them, i.e. modify or alter them in some way, or indeed completely replace them with something else entirely, such as a React component.

{% hint style="info" %}
For detailed explanations of processors please see the [reference page for the `<html2react>` package](https://api.frontity.org/frontity-packages/features-packages/html2react), and in particular [the section on processors](https://api.frontity.org/frontity-packages/features-packages/html2react#processors).

In addition our documentation contains a [guide to working with processors](/guides/using-processors) and there is also a discussion about processors in [one of the videos in the Frontity Talks series](https://www.youtube.com/watch?v=qOfENWKR7EE\&list=PLC9teX20GdrTBeOzSwE-bFW-MbBEUwowS\&index=10\&t=1272s).
{% endhint %}

## Examples

In these examples we will illustrate how you might work with content from Gutenberg and from Elementor in a Frontity project. We will look at what we might need to include in our Frontity project, which is mainly copying `.css` files that the page builder uses, and also illustrate using a processor to dynamically process elements.

### Gutenberg

#### Processing Gutenberg content

In this example we will illustrate how a processor can work on an element created by Gutenberg.

{% hint style="info" %}
For further ideas and information [the repository for the Frontity.org site](https://github.com/frontity/frontity.org/tree/dev/packages/frontity-org-theme) contains a [large number of examples of processors](https://github.com/frontity/frontity.org/tree/dev/packages/frontity-org-theme/src/processors) that you can examine for the details of technical implementation in various cases.
{% endhint %}

Let's use as our example here one of the processors from that repository. We will choose [the `webBrowser` processor](https://github.com/frontity/frontity.org/blob/dev/packages/frontity-org-theme/src/processors/web-browser.tsx).

Gutenberg allows you to add classes to any block. You can do this under Settings → Block → Advanced → Additional CSS class(es).

![](https://frontity.org/wp-content/uploads/2021/06/processing-page-builder-content-img01.png)

In the screengrab above we've added the `has-browser-window` class.

Gutenberg stores the content for a page/post as HTML in the database, adding this class along with Gutenberg's native classes which it uses to correctly render the elements of the page/post.

This HTML is then available to us in the `content.rendered` property received from the REST API. We can therefore simply parse this HTML with the `html2react` component to identify the elements we want to process.

The `webBrowser` processor tests whether the element has the `has-browser-window` class and if so executes the processor function which adds a top bar to the element to create the effect of being in a browser window:

![](https://frontity.org/wp-content/uploads/2021/06/processing-page-builder-content-img02.png)

The processor first imports a [`<Topbar>` component](https://github.com/frontity/frontity.org/blob/dev/packages/frontity-org-theme/src/components/window-top-bar.tsx) which renders the actual top-bar. It then adds it as the first element in the node's `children` array (using [unshift](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/unshift)). Adding it as the first element in the array ensures that it will appear above the remaining child elements, creating the browser window effect.

```jsx
import TopBar from "../components/window-top-bar";

export const webBrowser = {
  name: "web-browser",
  test: ({ node }) =>
    node.type === "element" &&
    node.props?.className?.split(" ").includes("has-browser-window"),

  processor: ({ node }) => {
    const topFrame: Element = {
      type: "element",
      component: TopBar,
      props: {},
    };

    node.children.unshift(topFrame);

    node.props.css = css`
      // styles go here
    `;

    return node;
  },
};
```

The processor then merely adds some styling, using the [`<css>` object](https://api.frontity.org/frontity-packages/core-package/frontity#css), before returning the node.

#### Gutenberg stylesheets

One additional important thing that we need to do to ensure that our Gutenberg content is rendered correctly is to import Gutenberg's style sheets into our Frontity project.

Gutenberg uses two stylesheets, `theme.css` and `style.css`. These files can be found in the `./wp-includes/css/dist/block-library` directory of your WordPress installation. Copy them across to a location in your Frontity theme, e.g. to a sub-directory called `styles`.

You should then import them into the `index.js` file of your Frontity theme and add them using the [`<Global>` component](https://api.frontity.org/frontity-packages/core-package/frontity#global).

```jsx
import { connect, css, Global, Head, styled } from "frontity";
import gutenbergStyle from "./styles/style.css";
import gutenbergTheme from "./styles/theme.css";

const Theme = ({ state }) => {

  ...

  return (
    <>
      <Global styles={css(gutenbergStyle)} />
      <Global styles={css(gutenbergTheme)} />

      ...

    </>
  );

};
```

{% hint style="info" %}
See [this blog post](https://frontity.org/blog/connecting-gutenberg-and-frontity/) which discusses some of the considerations that went into making Gutenberg and Frontity work together in the development of the frontity.org site. The [section on `html2react`](https://frontity.org/blog/connecting-gutenberg-and-frontity/#frontity-html2react) is particularly pertinent here and contains further examples.
{% endhint %}

### Elementor

Getting Elementor content to appear as desired in a Frontity project is a bit clunkier and less elegant than working with Gutenberg content.

However, Elementor is an immensely popular page-builder plugin, so it's worth going over the steps needed to get Element content to render properly in a Frontity project.

#### Processing Elementor content

Processing Elementor content is no different to processing Gutenberg content, or indeed any other content. We will therefore not go over the process again here. Please refer to the section above on [processing Gutenberg content](#processing-gutenberg-content), or see our guide to [working with processors](/guides/using-processors).

As with any content the best way to decide what and how to implement a processor is to examine the HTML generated by the standard WordPress theme and identify the elements and classes that are added to the markup.

#### Elementor stylesheets

There are a number things that need to be taken into account here in order to get Elementor content to render correctly in a Frontity project.

Like with Gutenberg, it's necessary to copy Elementor's CSS files over to your Frontity project. However, with Elementor there are several files in two different locations.

You will need Elementor's `frontend.min.CSS` file which is located in the `wp-content/plugins/elementor/assets/css/` directory.

Elementor also puts files in `wp-content/uploads/elementor/css`. In particular you will need `global.css` from this directory.

Copy these two files across to your Frontity project and import them into your main `<Theme>` component in your theme's `index.js` file:

```js
import ElementorStyles from "../assets/frontend.min.css"
import ElementorGlobalStyles from "../assets/global.css"

const Theme = ({ state }) => {

  // ...

  return (
    <>
      {// ...}
      <Global styles={css(ElementorStyles)} />
      <Global styles={css(ElementorGlobalStyles)} />
      {// ...}
    </>
  )
}
```

Elementor may put other post or page specific stylesheets in the `wp-content/uploads/elementor/css` directory. These will usually each be specific to a particular page or post.

You should copy any that you find there (or at least any that you identify that you will need) to your Frontity project and import them into your Frontity theme, for example *(the filenames in your project may differ)*:

```js
import ElementorPost6Styles from "../assets/post-6.css"
import ElementorPost8Styles from "../assets/post-8.css"

const Theme = ({ state }) => {

  // ...

  return (
    <>
      {// ...}
      <Global styles={css(ElementorPost6Styles)} />
      <Global styles={css(ElementorPost8Styles)} />
      {// ...}
    </>
  )
}
```

{% hint style="warning" %}
Remember that the preferred way of styling a Frontity project is to use CSS in JS, and the benefits of CSS in JS are lost when adding style sheets to the project using the `<Global />` component. Adding stylesheets in this way can potentially affect the performance of the site.

You may need to add several `.css` files from Elementor in this way in order to accurately reproduce the look and feel of the content in your Frontity project, so keep in mind the potentially adverse effect of this on the performance of your site.
{% endhint %}

#### Elementor classes

A complication that needs to be taken into account is that Elementor adds classes to the `<body>` tag. However, you can add these same classes to the `<body>` tag of your Frontity project using the [`<Head>` component](https://api.frontity.org/frontity-packages/core-package/frontity#head).

First import the `<Head>` component into your theme's `index.js` file and then use it in your main `<Theme>` component passing it a `bodyAttributes` prop containing an object with the classes that you want in your `<body>` tag.

```js
import { Head } from "frontity";

const Theme = ({ state }) => {

  // ...

  return (
    <>
      {// ...}
      <Head bodyAttributes={{
        class: 'elementor-default elementor-page elementor-kit-8'
      }} />
      {// ...}
    </>
  )
}
```

{% hint style="info" %}
**Note** that the classes that you need for your project may differ from those in the example above. The easiest way to find out what classes you need is to inspect the HTML of the page generated by WordPress.

You may not need all the classes that you find in the `<body>` tag there. WordPress itself adds certain classes, and your WordPress theme may well be adding classes of it's own.

So you will need to identify which are the Elementor classes. This should be pretty easy as they usually start with `elementor-`, however a trial-and-error approach is needed here to see which classes added to the `<body>` tag produce the desired result in the browser.
{% endhint %}

{% hint style="info" %}
**Note also** that live reload doesn't work when you add or edit `<Head>` components to your theme. You will need to manually refresh your browser in order to see the new classes added to the `<body>` tag.
{% endhint %}


# Keep Frontity Updated

As in most projects, keeping Frontity and its packages updated is always a good practice. Not only you could use new features added, but also some security issues are usually detected and solved during these updates.

At this point, it is important to distinguish between your **dependencies** (npm packages you won't modify and reside in `/node_modules` folder) and your **local packages** (packages you create or change at your will, and reside in `/packages` folder). For more info you can check the page [Learning Frontity - Packages](/learning-frontity/packages).

### Update project dependencies

Essential packages such as `frontity`, `@frontity/core` or `@frontity/tiny-router`, and all your dependencies, are included in this part. These can be treated as common npm packages, so you can use the following command to update your `package.json` to the latest versions:

```bash
npx npm-check-updates -u -t minor
npm install
```

{% hint style="info" %}
Note that using the `-t minor` switch ensures that only minor updates will be applied. This avoids introducing potential breaking changes that a major update might introduce. [See here](https://github.com/raineorshine/npm-check-updates) for more info.
{% endhint %}

With this, **you will update your `package.json` and all your dependencies in `node_modules`**, including the Frontity packages installed in **`node_modules`**.

If you want to update just one package you can do it with this other command:

```bash
npm install my-package@latest
```

### Update local package dependencies

These local packages, included in `packages` folder, are supposed to be modified by the users, so any dependency won't be updated when you update your project dependencies.

To update the dependencies of your local package dependencies, go to their folder and run the same command:

```bash
cd package/my-local-package
npx npm-check-updates -u -t minor
# DO NOT RUN "npm install" this time!
```

Do that for each local package found in your `packages` folder.

After you've finished, go to the root folder of your Frontity project and run `npm install` there:

```bash
cd ../.. # Go back to the root folder
npm install
```

## Troubleshooting

### Delete all the dependencies and start over

If you are having problems, follow these steps to install everything from scratch:

1. Make sure you have updated all your dependencies in:
   * The root `package.json` of your project.
   * All the `package.json` files of your local packages.
2. Delete all the `node_modules` folders of:
   * The root of your project.
   * All your local packages.
3. Delete all the `package-lock.json` file of:
   * The root of your project.
   * All your local packages.
4. Run `npm install` again.

Everything should work after this.

{% hint style="info" %}
Still have questions? Ask [the community](https://community.frontity.org/)! We are here to help 😊
{% endhint %}


# Troubleshooting

In this guide we offer solutions to common issues detected in Frontity projects

* [`@frontity/wp-source`](/guides/troubleshooting#frontity-wp-source)
  * [💻 FetchError: invalid json response body at ... reason: Unexpected token < in JSON at position 0](/guides/troubleshooting#fetcherror-invalid-json-response-body-at-reason-unexpected-token-less-than-in-json-at-position-0)
* [Frontity CLI](/guides/troubleshooting#frontity-cli)
  * [💻 Error: Cannot find module ‘@frontity/core’](/guides/troubleshooting#error-cannot-find-module-frontity-core)
* [Styles](/guides/troubleshooting#styles)
  * [👨‍💻 The pseudo class ":xxx-xxxxx" is potentially unsafe when doing server-side rendering. Try changing it to ":xxx-xxxxx"](/guides/troubleshooting#the-pseudo-class-xxx-xxxxx-is-potentially-unsafe-when-doing-server-side-rendering-try-changing-it-to-xxx-xxxxx)

{% hint style="info" %}
These are the symbols used in this troubleshooting guide

* 💻 Terminal messages
* 👨‍💻 Browser's console messages
  {% endhint %}

## `@frontity/wp-source`

### 💻 FetchError: invalid json response body at ... Reason: Unexpected token < in JSON at position 0

If you launch your site locally with `npx frontity dev` and you get this in the browser

```
Internal Server Error
```

And you get something like this error in the terminal when attempting to load the page in the browser:

```
FetchError: invalid json response body at http://wptest.test/wp-json/wp/v2/posts/?_embed=true&page=1 reason: Unexpected token < in JSON at position 0
```

It may be because your WP doesn't have permalinks activated (which is a requisite of the `@frontity/wp-source` package)

#### Solution

From your WP, go to `Settings -> Permalinks` and check one of the pretty permalinks options, rather than the plain one:

![](https://frontity.org/wp-content/uploads/2021/04/wordpress-permalink-setting.png)

**Related Threads**:

* <https://community.frontity.org/t/frontity-not-working-with-plain-permalinks/1428>

## Frontity CLI

### 💻 Error: Cannot find module ‘@frontity/core’

If you get this error in the terminal when you do `npx frontity serve`:

```
Error: Cannot find module ‘@frontity/core’
home/lib/node_modules/frontity/dist/src/cli/index.js
home/lib/node_modules/frontity/dist/src/commands/serve.js
home/lib/node_modules/frontity/dist/src/cli/serve.js
```

This may be caused because you're not executing this command from the root of your Frontity project (maybe you're launching it from the `build` folder)

#### Solution

Run `npx frontity serve` from the root of your Frontity project

**Related Threads**:

* <https://community.frontity.org/t/error-cannot-find-module-frontity-core/2180>

## Styles

### 👨‍💻 The pseudo class ":xxx-xxxxx" is potentially unsafe when doing server-side rendering. Try changing it to ":xxx-xxxxx"

If you are getting these types of warnings in the console:

```
The pseudo class ":nth-child" is potentially unsafe when doing server-side rendering. Try changing it to ":nth-of-type"
The pseudo class ":first-child" is potentially unsafe when doing server-side rendering. Try changing it to ":first-of-type".
```

This is caused by an [`emotion`](https://github.com/emotion-js/emotion) issue: <https://github.com/emotion-js/emotion/issues/1105>

As [emotion is used internally](https://docs.frontity.org/learning-frontity/styles#emotion-documentation) by Frontity our code should take into account what can and cannot be done using CSS in JS with emotion

This is NOT an issue that should be ignored or "fixed" under normal circumstances. We recommend you use the following solutions only if you're getting these messages because of some third-party CSS that you don't have no control over (e.g. from a CSS framework or a component library or another external source).

#### Solution 1

For this specific issue, there's [this solution](https://github.com/emotion-js/emotion/issues/1105#issuecomment-557726922) that seems to work pretty well to solve this issue in a Frontity project

**`components/index`**

```
import { CacheProvider } from '@emotion/core'
import createCache from '@emotion/cache'

const myCache = createCache()
myCache.compat = true

<CacheProvider value={myCache}>
  <App/>
</CacheProvider>
```

#### Solution 2

You could also define functions to search and replace the selectors causing the warnings by the recommended ones

**`helpers/css`**

```
export const nthChildToNthChildType = css => css.replace(/\:nth\-child/g, `:nth-type`)
export const firstChildToFirstOfType = css => css.replace(/\:first\-child/g, `:first-of-type`)

export const fixCss = css => firstChildToFirstOfType(nthChildToNthChildType(css))
```

So then you can do in your code...

**`components/index`**

```
import React from "react";
import { Global, css, connect, styled, Head } from "frontity";
...
import gutenbergThemeCSS from "../styles/theme.min.css";
import gutenbergStyleCSS from "../styles/style.min.css";
...

import {fixCss} from '../helpers/css'
const fixedGutenbergThemeCSS = fixCss(gutenbergThemeCSS)
const fixedGutenbergStyleCSS = fixCss(gutenbergStyleCSS)


const Theme = ({ state }) => {

  ...
  return (
    <>
      ...
        <Global styles={css([fixedGutenbergThemeCSS, fixedGutenbergStyleCSS])} />
      ...
    </>
  );
};

...
```

**Related Threads**:

* <https://community.frontity.org/t/bootstrap-the-pseudo-class-first-child-is-potentially-insecure-when-processed-on-the-server-side-try-changing-it-to-first-type/1811>


# JavaScript

In order to understand how **Frontity** works and be able to modify its files and develop your own project, it is necessary to understand the main JavaScript concepts that we use in our code. The number of concepts can seem overwhelming, but most of them are pretty simple.

{% hint style="info" %}
Note this guide's purpose is to give you a better understanding of which JavaScript concepts we use at **Frontity** and a brief explanation of them. If you want a more detailed way of learning JavaScript, you can check other guides like [freeCodeCamp](https://www.freecodecamp.org/) or [w3schools](https://www.w3schools.com/js/default.asp).
{% endhint %}

* [**JavaScript concepts**](/guides/javascript-basics#javascript-concepts)
  * [Comments](/guides/javascript-basics#comments)
  * [Variables](/guides/javascript-basics#variables)
  * [Strings](/guides/javascript-basics#strings)
  * [Numbers](/guides/javascript-basics#numbers)
  * [Objects](/guides/javascript-basics#objects)
  * [Arrays](/guides/javascript-basics#arrays)
  * [Functions](/guides/javascript-basics#functions)
  * [Operators](/guides/javascript-basics#operators)
  * [If-else](/guides/javascript-basics#if-else)
  * [Switch](/guides/javascript-basics#switch)
  * [For loops](/guides/javascript-basics#for-loops)
  * [While loops](/guides/javascript-basics#while-loops)
  * [Regular expression](/guides/javascript-basics#regexp)
* [**ES6 concepts**](/guides/javascript-basics#es6-concepts)
  * [Variables (let & const)](/guides/javascript-basics#variables-let-and-const)
  * [Arrow functions](/guides/javascript-basics#arrow-functions)
  * [Default parameters](/guides/javascript-basics#default-parameters)
  * [Destructuring assignment](/guides/javascript-basics#destructuring-assignment)
  * [Template strings](/guides/javascript-basics#template-strings)
  * [Import and export](/guides/javascript-basics#import-and-export)

## JavaScript Concepts

### Comments

As with most programming languages, you are able to include comments in your code. You can write single-line comments with `//` and multi-line comments between `/*...*/`

```javascript
// Single-line comment.
/*
Multi-line comment.
*/
```

### Variables

You can store data inside variables in order for it to be used later. For creating one you just have to define it and assign a value.

```javascript
var number1 = 3;
var number2 = 2;
var total = number1 + number2 // Total value would be 5.
```

JavaScript variables can hold many **data types**: numbers, strings, objects and more.

Since the [ES6 update](https://www.freecodecamp.org/news/write-less-do-more-with-javascript-es6-5fd4a8e50ee2/) there are other ways of declaring variables. We explain them later [ES6 variables (let, const)](/guides/javascript-basics#variables-var-let-and-const).

### Strings

Strings are used for storing text and can be defined between double or single quotes.

```javascript
var text1 = "This is a string";
var text2 = 'This is also a string';
```

{% hint style="info" %}
(Optional) There are some specific methods to work with strings that could be useful. To see some examples refer to [this guide](https://www.w3schools.com/js/js_string_methods.asp).
{% endhint %}

Since the [ES6 update](https://www.freecodecamp.org/news/write-less-do-more-with-javascript-es6-5fd4a8e50ee2/) there is also a new way of declaring strings that is more versatile than single or double quotes. We explain this later in [ES6 template strings](/guides/javascript-basics#template-strings).

### Numbers

Numbers can be written with or without decimals.

```javascript
var number1 = 5; // This is a number.
var number2 = 5.6; // This is also a number.
```

{% hint style="info" %}
(Optional) There are some specific methods to work with numbers too. You can view [this guide](https://www.w3schools.com/js/js_number_methods.asp) to see some examples.
{% endhint %}

### Objects

Objects are also variables, and they can store multiple values by assigning values to properties. You define objects this way:

```javascript
var person = {
  firstName: "Jon",
  lastName: "Snow",
  age: 40
};
```

This way, we have the variable `person` with as many properties-values as we want. You can access/modify the value of a specific property in two different ways:

```javascript
var name1 = person.firstName;
var name2 = person["firstName"]; // Both return the same value.
```

Object properties can also store other objects, like this:

```javascript
var person = {
  name: {
    first: "Jon",
    last: "Snow"
  },
  age: 40
};
```

### Arrays

Arrays store multiple values as a list of items.

```javascript
var pets = ['dog', 'cat', 'turtle'];
```

You can store as many items as you want, and they don't need to be strings, they can be anything you want, even objects. In order to access/modify an array item, you have to specify its position (starting at 0):

```javascript
var item1 = pets[0]; // Returns 'dog'.
var item2 = pets[1]; // Returns 'cat'.
var item3 = pets[2]; // Returns 'turtle'.
```

Arrays are an important part of JavaScript and there are lots of array methods that can simplify your code. You can check out an extended list of them at [w3schools array reference](https://www.w3schools.com/jsref/jsref_obj_array.asp). We consider the following especially interesting:

* [myArray.forEach()](https://www.w3schools.com/jsref/jsref_foreach.asp): to run a function for each array element.
* [myArray.filter()](https://www.w3schools.com/jsref/jsref_filter.asp): to create a new array with every element in an array that pass a test.
* [myArray.map()](https://www.w3schools.com/jsref/jsref_map.asp): to create a new array with the result of calling a function for each array element.

### Functions

A JavaScript function is a chunk of code intended to perform a specific task. You have to define it first and call it later. You can pass parameters to the function to return a different value depending on the parameters.

```javascript
// Defining the function.
function myFunction(parameter1, parameter2) {
  return parameter1 + parameter2;
}
// Calling the function with specific parameters.
myFunction(2, 3); // It will return 5.
myFunction(5, 4); // It will return 9.
```

Since the [ES6 update](https://www.freecodecamp.org/news/write-less-do-more-with-javascript-es6-5fd4a8e50ee2/) there are other ways of declaring functions that are commonly used and make your code easier to understand. We explain them later in [ES6 arrow functions](/guides/javascript-basics#arrow-functions).

### Operators

In JavaScript, there are many types of operators. We could divide them this way:

* **Arithmetic Operators:** To perform arithmetics like addition ( `+` ), subtraction (`-`), multiplication (`*`), etc.
* **Assignment Operators:** To assign values to variables (`=`).
* **Comparison Operators:** To test if a condition is true/false. It could be `x === y`, `x < 5`, `x > 20`...
* **Logical Operators:** To add some logic to the comparison statement.  For example in this statement`x < 5` **`&&`** `y > 25`  "x" must be less than 5 **AND** "y" must be more than 25.

{% hint style="info" %}
These are just some examples of JavaScript operators, there is a good summary at [**w3schools JavaScript Operators**](https://www.w3schools.com/js/js_operators.asp) to fully understand them.
{% endhint %}

In JavaScript the `==` and `!=` operators exist, but they are never used because sometimes they don't behave properly (i.e. `0 == ""` is true!). For that reason everybody always uses three equals: `===` and `!==` for comparisons.

### If-else

Conditional statements are used to run different code based on different conditions. You can define an `if-else` statement this way:

```javascript
if (condition1) {
  // Run this code if condition1 is true.
} else if (condition2) {
  // Run this code if condition2 is true.
} else {
  // Run this code if condition1 and condition 2 are both false.
}
```

You can add as many `else if` (each one with a condition) as you want, and it will run the code of the first one that matches true. Moreover, you can use `if-else` without any `else if`, or even without the `else` statement, and it will continue with the rest of the code if `condition1` is false.

{% hint style="info" %}
In React, `if-else` statements don't work. Instead, we have to use operators and ternary expressions. For more details, refer to [React basics - Special cases](/guides/react-basic#if-else-statements-dont-work).
{% endhint %}

### Ternary operator

In JavaScript there's another way to do conditionals: using [ternary operators](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Conditional_Operator).

```javascript
condition ? /* Runs when condition is true */ : /* Runs when condition is false */;
```

They are useful when defining variables, like this:

```javascript
// Assign the color blue when age is above 30 and yellow when it is below. 
var color = person.age > 30 ? "blue" : "yellow"
```

They are also useful in React, but we'll see that later.

### Switch

Switch statements are similar to `if-else`, and they let you run different code depending on a condition. This is the way to define them:

```javascript
switch(value) {
  case 1:
    // Run this code if value === 1.
    break;
  case 2:
    // Run this code if value === 2.
    break;  
  default:
    // Run this code if no case match.
}
```

Again, you can define as many cases as you want, and if none of them match, the default would run.

### For loops

This statement is really useful if you want to perform the same code a number of times but with different values. To do so you have to define 3 statements:

```javascript
for (i = 0; i < 5; i += 1) {
  // Code block to be executed.
}
```

* **Statement 1** (`i = 0`): The initial value when the loop starts.
* **Statement 2** (`i < 5`): The condition that has to match to finish the loop.
* **Statement 3** (`i += 1`): This is optional and is executed after each loop iteration. Usually used to change the value before running the next loop iteration.

{% hint style="info" %}
It is common to use `for loops` to run the same code for every array item. In these cases, we strongly recommend using the [forEach() method](https://www.w3schools.com/jsref/jsref_foreach.asp) instead.
{% endhint %}

### While loops

Related to `for loops`, `while loops` perform the same code while a condition is true. You have to make sure that you change the condition in the code so you don't create infinite loops.

```javascript
while (condition1) {
  // Code block to be executed.
}
```

There is a similar loop called `do/while` which is a variant of the `while loop`. The only difference is that it will execute the code block once, before checking if the condition is true, and continue while the condition is `true`.

```javascript
do {
  // Code block to be executed.
}
while (condition);
```

### Regular Expressions (Regular expression)

The Regular Expressions (Regular expression) are really useful in JavaScript as they let you match a pattern. They can be used, for example, for defining a more complex condition.

They can be overwhelming, so if you are not familiar with them don't worry. We would recommend you try to understand each particular case as you find them in our code and know that they exist as they could be useful in your code. Again, don't worry and just learn the concepts once you need them. This way, you will learn step by step and it will be easier.

{% hint style="info" %}
To learn the basics and help you understand or create some RegExps, you can use [w3schools guide](https://www.w3schools.com/js/js_regexp.asp), [freeCodeCamp regular expression](https://learn.freecodecamp.org/javascript-algorithms-and-data-structures/regular-expressions) and also [RegExr](https://regexr.com/) to test them.
{% endhint %}

## ES6 concepts

There are some features introduced with the [ES6 update](https://www.freecodecamp.org/news/write-less-do-more-with-javascript-es6-5fd4a8e50ee2/) that are widely used across Frontity:

### Variables (let and const)

We previously defined variables with the statement `var`; however, since ES6, it is not used at all. Instead, people use `let` and `const` :

* **Const** is used almost 100% of the time in Frontity, and it implies that the variable can't be reassigned, it has a constant value.
* **Let** is used when you want to iterate through your variable and you would like to reassign its value.

{% hint style="info" %}
There are slight differences between `let` and `var` too, and you can read about them [here](https://www.w3schools.com/jS/js_let.asp), but they are not that important and `var` is not commonly used anymore.
{% endhint %}

### Arrow functions

Arrow functions are a new way of defining functions that make them shorter. Here you can see an example of how to declare the same function with and without arrow functions:

#### *Without arrow functions*

```javascript
const hello = function(name){
    return 'Hi ' + name + ', nice to meet you!';
}
hello('Jon');
```

#### *With arrow functions*

```javascript
const hello = (name) => {
    return 'Hi ' + name + ', nice to meet you!'
};
hello('Jon');
```

As you can see, the common way of using them is deleting the word `function` and adding `=>` just after it.

Sometimes the syntax can be even smaller. If your function is just composed of a `return` statement, you can change the curly braces `{ }` for parentheses `( )`, delete the `return` statement, and it will return the whole function automatically.

```javascript
const hello = (name) => (
    'Hi ' + name + ', nice to meet you!'
);
hello('Jon');
```

You can avoid the parentheses too:

```javascript
const hello = (name) => 'Hi ' + name + ', nice to meet you!';
hello('Jon');
```

However, if you return an object, the parentheses are required:

```javascript
const hello = (name) => ({ firstName: name, lastName: "Snow" });
hello('Jon'); // Outputs { firstName: "Jon", lastName: "Snow" }.
```

{% hint style="info" %}
Note that **if we don't want the function to return**, for example if we are defining variables inside it, **we must use the curly braces**.
{% endhint %}

Finally, we can remove the parenthesis from the parameters if only one parameter is used:

```javascript
const hello = name => "Hi " + name + ", nice to meet you!";

const hello2 = (name, surname) => "Hi " + name + surname + ", nice to meet you!";
```

### Default parameters

You can set a default value for a parameter and it will be used if no other value is passed. To do so, you can use the operator `=` while defining the parameter.

```javascript
const hello = (name = "there") => "Hi " + name + ", nice to meet you" ;

hello("Jon"); // It will return "Hi Jon, nice to meet you".
hello(); // It will return "Hi there, nice to meet you".
```

### Destructuring assignment

This JavaScript expression is used to unpack values from arrays or objects properties. It can seem a bit weird at the beginning, but once you get used to it, it will remove a lot of lines of code from your project.

#### *Object destructuring*

As mentioned before, destructuring an object lets you assign the value of one property to a variable.

```javascript
const person = {
    name: "Jon",
    lastName: "Snow",
    age: 30
};
const { name, lastName } = person;

// You are assigning the value of person.name to a new variable called "name".
console.log(name); // Returns Jon.
console.log(lastName); // Returns Snow.
console.log(age); // ERROR: age is not defined.
```

As you can see above, you select all the variables you want to create using curly braces `{ }` which equates them to the object properties you want to get the values from. Here you have an example of how to assign values with/without destructuring:

```javascript
// With destructuring.
const { name, lastName, age } = person; 

// Without destructuring.
const name = person.name; 
const lastName = person.lastName;
const age = person.age;
```

We are only defining three variables above, but imagine if you had to define many variables!

**You can also assign a different name to the variables** if you want. For example:

```javascript
const { name: a, lastName: b } = person

console.log(a); // Returns person.name.
console.log(b); // Returns person.lastName.
```

This way you are getting the value of `person.name` and storing it in a variable called "a".

Moreover, you can define a default value for a variable as mentioned [before](/guides/javascript-basics#default-parameters), just in case the object doesn't have that property defined.

```javascript
const person = {
    name: "Jon",
    lastName: "Snow",
    age: 30
};
const { name, lastName, family = "Stark" } = person;

console.log(family); // Returns Stark even though it's not defined in person.
```

#### *Array destructuring*

They work in a similar way to objects:

```javascript
const items = [10, 20, 30, 40, 50];
const [a, b] = items;

console.log(a); // Returns 10.
console.log(b); // Returns 20.
```

Again, it is the same as object destructuring, but instead of using curly braces we use `[ ]` because we are working with arrays, and it will get values depending on the position.

You can also use default values in case the array length is smaller than the variables defined.

```javascript
const items = [10, 20];
const [a = 35, b = 45, c = 55] = items;

console.log(a); // Returns 10.
console.log(b); // Returns 20.
console.log(c); // Returns 55.
```

Since `items` has just two elements, the first two variables are assigned values from the array while `c` gets its default value.

{% hint style="info" %}
If you have any questions or you want more information about array and object destructuring, refer to [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment) for a more detailed explanation.
{% endhint %}

### Template strings

Template strings (also called template literals) are just an easier way to work with strings. To define them you have to use back-ticks ( \`\` ). The main advantages of template strings are:

* They allow embedded expressions.
* You can use multi-line strings, just by adding a line-break.

Here is an example:

```javascript
const name = "Jon Snow";

const text = `Hi there!
I am ${name},
and I have killed ${43 + 57} white walkers`;
```

{% hint style="info" %}
There are more advantages of working with template strings, and you can check them out in guides like [MDN web docs](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals) or [Google docs](https://developers.google.com/web/updates/2015/01/ES6-Template-Strings).
{% endhint %}

In Frontity, we will mainly use them for styling, but you can find them in other parts of the code as well.

### Import and export

JavaScript lets you export functions (including components), classes, objects, or anything else from one module in order to be used in other programs. The same way you can reuse the ones written by external programs.

The import and export statements are exactly for this. If you want anything from your module/file to be reused somewhere else, you will use **`export`**, and if you want to use anything external, you will use **`import`**.

#### *Export*

There are two different types of export, **named** and **default**, and depending on each one, the corresponding import will be different.

* **Named export:** You can have multiple named exports per module. It is useful to export many values, and import just the ones you need.

```javascript
export const Component1 = () => { /* Code of Component1. */ };
export const Component2 = () => { /* Code of Component2. */ };
```

You will be exporting two components, with different names. This will be useful in case you want to import just one of them in other files.

You can also export all the variables at once:

```javascript
const Component1 = () => { /* Code of Component1. */ };
const Component2 = () => { /* Code of Component2. */ };

export {
  Component1,
  Component2
};
```

* **Default export:** You have one default export per module, and it will be used for the default import.

```javascript
const Component = () => {};

export default Component;
```

#### *Import*

Depending on the export of the source file, the import will be slightly different.

* **From named export**: It is mandatory to use the name of the corresponding object and you have to include it between curly braces.

```javascript
import { Component1, Component2 } from "./file-name"
```

* **From default export:** Importing from a default export, you can use the name you prefer for your file, just don't include it between curly braces.

```javascript
import Component from "./file-name"
```

Note that in both methods you have to specify the file you are importing from.

{% hint style="info" %}
For more info about these statements you can visit the [import](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import) and [export](https://developer.mozilla.org/en-US/docs/web/javascript/reference/statements/export) documentation.
{% endhint %}

When you import stuff from files, you have to use `"./"` at the beginning. That way, JavaScript knows that it is a file. For example:

```javascript
import Component from "./file-name"
```

You can also go deep inside folders:

```javascript
import Component from "./some-folder/nested-even-more/file-name"
```

Or go up a level using `"../"` .

```javascript
import Component from "../../file-name" // Up two levels from the current folder.
```

When you import stuff from npm packages (the ones you install with `npm install`) you have to use the name of the package directly, without any `"./"` before. Like this:

```javascript
import Component from "some-package-name"
```

There are other important ES6 aspects, but understanding the ones above will give you a wide understanding of Frontity's code. Another important concept that is commonly used in React are classes, but since the introduction of hooks, they are no longer needed and are not used at all in Frontity core.

{% hint style="info" %}
(Optional)For more detailed guides about these concepts, including classes, you can visit <https://www.w3schools.com/react/react_es6.asp>.
{% endhint %}

{% hint style="info" %}
These are the main JavaScript concepts used in Frontity. If you understand them, you will be able to continue with [React basics](/guides/react-basic) to master Frontity. If you want to delve deeper into learning JavaScript, there are a lot of resources out there, and if you have questions don't hesitate to ask [our community](https://community.frontity.org/c/dev-talk-questions) ☺️.
{% endhint %}


# React

In order to master Frontity and the React aspects needed for it, you should first understand HTML and [JavaScript's](/guides/javascript-basics) basic concepts.

As you may know, React is a JavaScript library that lets you build amazing user interfaces in an easy way, while having outstanding web performance. It has a lot of functionalities, but just the key concepts are needed in order to understand and use it with Frontity. We take care of the rest.

These are the concepts you should familiarize yourself with:

* [JSX](/guides/react-basic#jsx)
* [Elements](/guides/react-basic#elements)
* [Components](/guides/react-basic#components)
* [Props](/guides/react-basic#props)
* [Hooks](/guides/react-basic#hooks)
* [Special cases](/guides/react-basic#special-cases)
* [State manager - Frontity Connect](/guides/react-basic#state-manager-frontity-connect)

{% hint style="info" %}
Note that this guide's purpose is to give you a better understanding of React concepts you need to learn in order to understand Frontity by providing a brief explanation. If you want a more detailed explanation or want to learn more about React, you can check out their own docs: [React docs](https://reactjs.org/docs/hello-world.html).
{% endhint %}

## JSX

JSX (JavaScript XML) is an extension to the JavaScript language syntax. This allows you to use JavaScript logic within HTML, which makes your coding experience better and your code more readable. However, there are some differences we have to keep in mind:

* In order to use JavaScript inside HTML, you simply include the code you want to be treated as JavaScript within curly braces **`{ 'This would be javascript' }`**.
* You **can't use the word `class`** to define HTML classes, as it is reserved for JavaScript. Instead, you have to use **`className`**.
* The naming convention for **all HTML attributes and event references in JSX is camelCase**. For example, a click event in JSX is onClick, instead of onclick.

Here you have an example of a React element using a JavaScript variable (between curly braces) inside it.

```jsx
const name = 'Jon';
const Example = () => (
    <div className='main-section'>
        <p>Hi {name}, nice to meet you</p>
    </div>
);
```

## Elements

Elements are the smallest building blocks of React. They should not be confused with [components](/guides/react-basic#components). Elements are what components are made of.

* **All elements must be closed**. For example, line breaks must be coded as `<br />` . `<br>` is not valid.
* Any element **can be written with a self-closing tag**. For example, a `<div>`can be written as `<div />` or `<div>something inside</div>`. The difference is that in the first syntax version there is no way to include anything inside it.

## Components

Components are the core of React. They are reusable pieces of code intended for one specific job, usually to render some HTML. There are some aspects you should take into account:

* A React component **must start with a Capital letter**.

```jsx
const Example = () => <div><h1>Website title</h1></div>;
```

* **There must be a parent element** wrapping the rest of the nested elements. If no parent is needed, you can use `<>` and `</>` .

```jsx
const Example = () => (
  <>
    <h1>Website title</h1>
    <h2>Website description</h2>
  </>
);
```

* You can use **components inside components**.

```jsx
const Title = () => <h1>Website title</h1>;
const Description = () => <h2>Website description</h2>;

const Example = () => (
  <>
    <Title />
    <Description />
  </>
);
```

* You can differentiate React components from common HTML because they start with Capital letters.

```jsx
import { Div } from "./components";

const Example = () => (
  <>
    <div>This is inside a normal div tag</div>
    <Div>This is inside a React component called Div</Div>
  </>
);
```

There are two ways to create React components, although we recommend sticking only to function components.

***Function components:*** Components built using a function. They can be created with regular functions or arrow functions, although the second way is more common.

These two are equivalent:

```jsx
function Example() {
    return <div><h1>Website title</h1></div>;
}

const Example = () => <div><h1>Website title</h1></div>;
```

***Class components:*** They are created using JavaScript classes. All the things that required classes in the past can now easily be done with [React hooks](/guides/react-basic#hooks) (explained later) so we won't explain classes in detail.

{% hint style="info" %}
If you want, you can take a look at [React docs](https://reactjs.org/docs/components-and-props.html), since some other tutorials or external npm packages may still use them.
{% endhint %}

```jsx
class Example extends React.Component {
    render() {
        return <div><h1>Website title</h1></div>;
    }
}
```

## Props

If we think about React components as functions, props would be the parameters. Depending on the props you pass to the component, the result will be different. This lets you reuse your components depending on the input. Here you have an example of how to define a component with props and how to use it with specific values:

***Create the component with props***

```jsx
const Example = (props) => <h1>Hi {props.name}, nice to meet you!</h1>;
```

You can also use [ES6 destructuring](/guides/javascript-basics#destructuring-assignment) to extract the props directly in the function definition:

```jsx
const Example = ({ name }) => <h1>Hi {name}, nice to meet you!</h1>;
```

***Render the component with specific props***

```jsx
<Example name='Jon' /> // Outputs: <h1>Hi Jon, nice to meet you!</h1>

<Example name='Sansa' /> // Outputs: <h1>Hi Sansa, nice to meet you!</h1>
```

There are some things you have to know about props:

* You can use variables, objects, arrays or **anything you want as props**.
* You can **create a default value for the prop** in case it is not passed when the component is used, so it renders something instead of leaving it blank.

```jsx
const Example = ({ name = "Aria" }) => <h1>Hi {name}, nice to meet you!</h1>;
```

In this case, if we use the component without the name prop (`<Example />`), the value will be `Hi Aria, nice to meet you!`.

* You can use the **prop children** to pass down the content included inside the component tags:

```jsx
const Example = ({ children }) => (
  <div className='mainContainer'>
    {children}
  </div>
);
```

This let you include any content inside the `<div>`, just by nesting elements inside the Component:

```jsx
<Example>
    <h1>Hi there!</h1>
</Example>
```

This will place the `<h1>` where we defined the `children`, so the final HTML would be:

```jsx
<div class='mainContainer'>
    <h1>Hi there!</h1>
</div>
```

## Hooks

Hooks are a new concept introduced by React that lets you reuse logic between components in an easy way. There are lots of hooks created already, and you can also create your own hooks. For now, we will focus on understanding two basic ones:

### useState

React components can have their own internal state.

This hook lets you create local state variables for components without using classes and with a really simple method:

```jsx
const state = useState(initialValue);

// "state" is an array. The first item is the value of the state:
const value = state[0];
// and the second is a function to change it:
const setValue = state[1];
```

You can also use [ES6 destructuring](/guides/javascript-basics#destructuring-assignment) to get the first and second value of the array directly in the assignment.

```jsx
const [value, setValue] = useState(initialValue);
```

We are using

* **`value`**: the name of the state variable you want to be changed after any events you define.
* **`setValue`**:  the name of the function we will use to update the value of `value`.
* **`initialValue`**: the value of `value` at the first render.

Let's see another example. We will create a count with initial value `0` and two buttons to update it: one to update the value directly to `5` when clicking it, and the other one to add `1` to the actual count:

```jsx
const Example = () => {
    const [count, setCount] = useState(0);
    return (
        <div>
            <h1>Value: {count}</h1>
            <button onClick={() => setCount(5)}>Set value to 5</button>
            <button onClick={() => setCount(count + 1)}>Sum 1</button>
        </div>    
    );
}
```

This is the basic functionality of this hook, and it is enough to understand how we use it in Frontity. It has more features which you can check out at [React docs](https://reactjs.org/docs/hooks-state.html).

### useEffect

This hook lets you run code after the component has been mounted to the DOM and each time it is rendered again. A good example of where to use this hook could be subscriptions or data fetch.

To use it we must define a function inside it. The code inside this `useEffect` will run each time the component re-renders.

```jsx
useEffect(() => {
    // Whatever you want to perform after each render.
});
```

If you want the code to run just once on the first render, you can specify it by adding an empty array `[]` as a second argument.

```jsx
useEffect(() => {
    // Whatever you want to perform only on the first render.
}, []);
```

For example, Frontity uses this to fetch the next post once the initial one has been rendered. This won't affect the initial load and will make the load of the next post instant.

Finally, if you want to run code each time a prop changes, you can include that prop in the array of the second argument, like this:

```jsx
const Example = ({ name }) => {
    useEffect(() => {
        // Whatever you want to perform on the first render and
        // each time `name` changes.
    }, [name]);

    return <h1>Hi {name}, nice to meet you!</h1>;
}
```

This is the basic functionality of this hook, and it is enough to understand how we use it in Frontity. It has more features which you can check out at [React docs](https://reactjs.org/docs/hooks-effect.html).

## Special cases

### If-else statements don't work

In JSX, we can't use if-else statements, but don't worry, we can use operators and ternary expressions:

* We can use **the operator &&** (`condition && resultIfTrue`) when we want to return something if the condition is true, and nothing if not. In the example below, it will return the `<p>It is right</p>` element if value is > 20 and nothing if it isn't.

```jsx
const Example = ({ value }) => (
    <div>
        <h1>Hi there!</h1>
        {value > 20 && <p>It is right!</p>}
    </div>
);
```

* We can use a **ternary expression** (`condition ? resultIfTrue : resultIfFalse`) if we want to return something if the statement is false. In the example below, it will return the `<p>It is right</p>` element if value is > 20 and will render `<p>It is NOT right</p>` if that statement is not true.

```jsx
const Example = ({ value }) => (
    <div>
        <h1>Hi there!</h1>
        {value > 20 ? <p>It is right!</p> : <p>It is NOT right!</p>}
    </div>
);
```

If you don't want to return anything in a ternary expression, you can return `null`:

```jsx
const Example = ({ value }) => (
    <div>
        <h1>Hi there!</h1>
        {value > 20 ? <p>It is right!</p> : null}
    </div>
);

<Example value={3} />
```

*This is actually the same behaviour as the first example.*

### **Arrays must have keys**

One of the benefits of React is that it only updates DOM elements that have changed which improves the performance of the web. This is important in order to understand why **while iterating through an array, its elements must have a key**. If you don't define a key, it may cause some trouble.

Keys help React identify which items have changed, are added, or are removed. We can see keys as unique identifiers for each element.

Let's look at an example where we are using the `map()` method:

```javascript
const items = [
    { title: "title 1", id: 23 },
    { title: "my other title", id: 45 },
    { title: "another one", id: 72 },
];

{items.map(item => <Item key={item.id} item={item} />)}
```

Imagine that we reorder the titles and the third object, with ID 72, moves to the second place. If we don't define a key, React would interpret that both objects (IDs 45 and 72) have changed, when they have just reordered, and React would re-render them.

By defining a key with an unique id, React would be able to understand that the title of ID 45 is still the same, as well as ID 72, and they have just reordered. This may not seem useful, but if you are working with big objects, it can save a lot of resources.

This is just an example of why it is important to assign keys properly to arrays. To learn more you can visit [React docs](https://reactjs.org/docs/lists-and-keys.html).

{% hint style="info" %}
These are the main React concepts used in Frontity. If you understand them, you will be able to understand Frontity code. If you want to delve deeper into learning React, we recommend you refer to [their docs](https://reactjs.org/docs/hello-world.html), and if you have questions don't hesitate to ask them of [our community](https://community.frontity.org/c/dev-talk-questions) ☺️.
{% endhint %}

## State Manager - Frontity Connect

Usually React is used with a State Manager that exposes a global `state` tree which can be accessed from any component of the app. This helps you keep different components in sync, and it is also a medium to communicate between them.

There are many state managers, like Redux or Mobx, but in **Frontity** we have created our own state manager named **Frontity Connect.** To learn more see [Learning Frontity - State](/learning-frontity/state)

Here is an example of how `state` is used and how easy it is to manage it with **Frontity Connect**. As said before, you should imagine the state as an object with info about the app:

```javascript
{
 state: {
    frontity: {
        title: "My awesome blog",
        description: "The best place to read about awesome things",
        ...
    },
    theme: {
        menu: ["Home", "Nature", "Travel"],
        ...
    },
    ...
}
```

With this in mind, you can use all this info in your components and change it depending on different events. In order to use the global state properly inside a component, you have to:

* Import `connect` from the `"frontity"` package.
* Pass `state` as a prop in the component.
* Connect the component after defining it with `connect(Component)` .

```jsx
import { connect } from "frontity";

const Component = ({ state }) => (
    <h1>{state.frontity.title}</h1>
);

const ConnectedComponent = connect(Component);
```

It's common to use `connect` only on the default export of the file:

```jsx
import { connect } from "frontity";

const Component = ({ state }) => (
    <h1>{state.frontity.title}</h1>
);

export default connect(Component);
```

Now, if you create an action that changes the title after a user interaction, this component will be updated with the new title.

**Frontity Connect** can also be used to pass `actions` and `libraries` to the components, like this:

```jsx
import { connect } from "frontity";

const Component = ({ actions, libraries, content }) => {
    const HTML2React = libraries.html2react.Component;
    const changeTitle = () => actions.theme.changeTitle("Other Title");

    return (
        <>
            <button onClick={changeTitle}>
                Change title
            </button>
            <HTML2React html={content} />
        </>
    );
};

export default connect(Component);
```


# Contributing

Want to contribute to the project? That's great to hear! You can find more information in the following pages.

{% content-ref url="/pages/-M3z\_PfE2tRZ8nRX2yNV" %}
[How to contribute?](/contributing/how-to-contribute)
{% endcontent-ref %}

{% content-ref url="/pages/-M4Ixo0YGS5\_PAMhHrDM" %}
[Contributing Guide](/contributing/code-contribution-guide)
{% endcontent-ref %}

## Why to contribute?

As you may know, Frontity is an open source project, available and free for everyone. We believe that working in an open way and sharing knowledge has the power to change the world for the better.

Here are some more good reasons to contribute to open source:

* **Build new connections**: an open source community usually consists of people sharing similar interests, so contributing to a project will allow you to connect with amazing people.
* **Improve your skills and competences**: if you want to practice your programming skills, there is always a task for you in open source projects. This will allow you to improve your knowledge.
* **Learn from mentors and teach others**: collaborating with others on a shared project means you'll have to ask people for help, as well as share your solutions and learnings with others. This can be a fulfilling activity for everyone involved.
* **Get recognition**: all your work is public so you can get more visibility and recognition from others. Apart from that, you are in the perfect spot to learn about forthcoming changes.
* **Your work matters**: you are able to make changes and improvements to a project - seeing how your work helps others is pretty gratifying.

These are only a few reasons, but there are many more.

If you want to contribute to Frontity Framework but don't know how or where to start, the [*How to contribute?*](/contributing/how-to-contribute) guide might help. Check it out!


# How to contribute?

There are several ways to support the project and get involved. Don't know how to code? Don't worry! You can contribute in many other ways to make Frontity awesome!

## » Improve Frontity Framework

* Suggest new features and improvements. The [Feature Discussions](https://community.frontity.org/c/feature-discussions/33) category of the forum is a great place to do so, also to vote for those features which you are most interested in. These are public conversations where everyone is welcome to join. Alternatively, you also can open a [Pull Request](https://github.com/frontity/frontity/pulls).
* Found a bug or issue? [Report it](https://github.com/frontity/frontity/issues) on GitHub.
* If you are interested in fixing bugs or contributing code, please refer to this [Code Contributions](/contributing/code-contribution-guide) guide.
* If you have built a new Frontity package or theme, consider submitting it to [npm](https://www.npmjs.com/). Making it available to the community it's also a good way to contribute to extend and improve the framework.

## 📖 Improve the documentation

* The Frontity documentation can easily be edited on GitHub. You can suggest improvements, fix mistakes or fill in the gaps in the docs at any time by following these [contributing guidelines](https://github.com/frontity/docs/blob/master/CONTRIBUTING.md).
* Alternatively, you can report them using the [community forum](https://community.frontity.org/c/framework-development/docs-and-tutorials/29).

## 👨‍👩‍👧‍👦 Join and support the community

* The [community forum](https://community.frontity.org/) is a great place to get support while helping others with your own questions. As you might have the same question of someone else, makes sense to share! You can join an existing conversation or start a new post in its relevant category. Learn how the forum is organized [here](https://community.frontity.org/t/frontity-community-forum-users-guide/4399#organized-in-categories).
* Answering [other users' questions](https://community.frontity.org/c/dev-talk-questions/3) in the community forum is one of the best and easiest ways to start contributing to Frontity. A single forum post can help a lot of people!
* Have you built a project with Frontity? Swing by the [Showcase](https://community.frontity.org/c/community/showcases/19) category and tell the community more about it. This is a great way to show what can be accomplished with the framework and to help inspire other developers with your work.

## 🗣 Spread the word

* Teach and help others by writing guides, tutorials or case studies about how you're using Frontity. You can share them with the community [here](https://community.frontity.org/c/community/resources/15).
* Talk about how you used Frontity and your success story with it at any local meetup, workshop, or relevant event.
* If you read a post on Reddit, Twitter, Dev.to, or other social platforms where Frontity could be relevant, let others know.
* Are you a freelancer looking for Frontity projects? Are you hiring developers? The [Jobs category](https://community.frontity.org/c/jobs/45) of the forum is a good place to post about it.

{% hint style="info" %}
Wondering why you should get involved? Check out [this post](https://opensource.guide/how-to-contribute/#why-contribute-to-open-source) about contributing to open source software.
{% endhint %}


# Contributing Guide

Frontity, as an open-source project, welcomes everyone to contribute to code, so we are trying to make it as easy as possible.

The most common way to suggest improvements or changes to Frontity (and most of the projects) is to [fork](https://docs.github.com/en/github/getting-started-with-github/fork-a-repo) the Frontity project to your own repository and make there all the changes you want. Once you consider they are okay, make a [pull request](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/creating-a-pull-request) to submit your contribution to Frontity.

{% hint style="info" %}
Before starting, the only **prerequisite is to have Node.js 10 installed in your computer**.
{% endhint %}

## Quick guide

1. Fork the official Frontity repository to your user account.
2. Clone your fork to your local machine
3. Run `npm install` from the root folder.
4. Run `cd examples/mars-theme-example/` to go to the example directory.
5. Run `npx frontity dev` to start Frontity with mars-theme on [localhost:3000](http://localhost:3000/).
6. Make any changes you consider to the code.
7. Run `npm test` from the root to check if the fork passes the tests.
8. Run the e2e tests `cd e2e && npm i && node e2e.js --cypress run —prod`
9. `commit` and `push` to your fork.
10. Open a [Pull Request](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/creating-a-pull-request) explaining your changes.

## Step by step guide

**1. Fork the** [**official Frontity repository**](https://github.com/frontity/frontity)**:**

You can go to [our repository](https://github.com/frontity/frontity/), click on **"Fork"** at the right-top corner and select your user.

![](https://frontity.org/wp-content/uploads/2021/04//frontity_frontity__-_frontity_-_create_amazing_sites_using_wordpress___react.png)

After doing this, you will create Frontity project at your own repository so you can access and modify it at: `https://github.com/YOUR_USERNAME/frontity/`

**2. Clone your own fork:**

In order to run the code from your local machine you have to clone your forked "Frontity" repository.

If you are not using a Git Graphical User Interface (like GitKraken or SourceTree), you can clone your fork from the console by doing the following:

```
git clone https://github.com/YOUR_USERNAME/frontity.git
```

This will create a folder named “frontity” inside the directory from where the `git clone` command was executed.

**3. Run `npm install` on the root folder:**

Run `npm install` from the root of the Frontity project ("frontity" folder)

> Make sure you don't run this from any of the packages folders.

{% hint style="warning" %}
`frontity` repository is a monorepo multipackage. Because of this you don't need to run `npm install` on any package under `packages` folder. By running `npm install` from the root all dependencies packages under `packages` folder will be properly installed
{% endhint %}

**4. Check the behaviour of your changes from an example project**

To view the result of your changes you can use some of the example projects that are under the `examples` folder

These Frontity projects are also part of the monorepo multipackage so:

* You don't need to do `npm install` individually on these example projects. The installation of dependencies in all packages of the repo (including these example projects) are handled *globally* by the `npm install` done from the root of `frontity` (step 3)
* The dependencies are installed in a way that are linked to the proper portion of code in the repo. This means that changes in the code will be reflected in the project
* You can use these projects to check the behaviour of the Frontity core code and the code of the packages used in the project&#x20;
* If the package you want to check is not a dependency of the example project you'll have to add it to be able to properly check it

**5. Run your local server:**

To check your modifications, choose one of the projects in the `examples` folder and, for example `mars-theme-example`, and run **`npx frontity dev`**. This will start Frontity with mars-theme on [localhost:3000](http://localhost:3000/) and it will open automatically a new tab on your browser.

You can also run `npm run build:watch` to automatically execute `npm run build` every time you save changes in the code of the packages that run before Webpack, like `file-settings`, `babel-plugin-frontity` or the scripts of `core`

**6. Make any changes you consider**:

Now you have the proper environment to do changes to the code (core and packages used by the example project) and check the behaviour. Changes you do in the code should be reflected in `localhost:3000`.

{% hint style="warning" %}
After adding/removing dependencies to any `package.json` (on any package under `packages` folder), you must go back to the root and do `npm install` again as you're working in a monorepo multipackage.
{% endhint %}

**7. Run the unit tests:**

Once you have finished adding changes to Frontity, your code must pass all the unit tests. Run `npm test` **from the root folder**. This command will tell you if your code pass all the tests, or if there's some test failing.

If you find some errors, you can try:

* Run `npm test` on a package to detect where is the problem.
* Run `npm run test:ci` in the root to pass all tests without cache. It is useful for TypeScript tests.

**8. Run the e2e tests:**

Your code must also pass all the end-to-end tests.

Go to the `e2e` folder and run:

```bash
cd e2e
npm install
node e2e.js --cypress run --prod
```

You need Chrome installed in your computer.

If you need to run the e2e tests in development mode, run:

```bash
node e2e.js
```

and Cypress will open.

Complete information about the e2e test in [this README file](https://github.com/frontity/frontity/blob/dev/e2e/README.md).

**9. Commit and push to your fork:**

Again, we recommend you to use a Git Graphical User Interface like GitKraken, but it can also be done from the command line if you want.

**10. Open a Pull Request**

At this point, your fork should be ready to be merged to Frontity, so you can open a Pull Request (PR) and we can review it. Make sure to select a descriptive name and follow the template.

For opening a PR you have to go to [Frontity's pull requests](https://github.com/frontity/frontity/compare) page and select **compare across forks.**

![](https://frontity.org/wp-content/uploads/2021/04//compare_-_frontity_frontity.png)

Select your own repository and **the dev branch** on Frontity, and **create the pull request**.

![](https://frontity.org/wp-content/uploads/2021/04//compare_-_frontity_frontity-2.png)

## Commit messages

Commit messages are one of the most common ways developers communicate with other developers so it’s important that your commit message clearly communicate changes with everybody else.

In Frontity, we follow [the seven rules of Chris Beams](https://chris.beams.io/posts/git-commit/#seven-rules):

1. Separate subject from the body with a blank line
2. Limit the subject line to 50 characters
3. Capitalize the subject line
4. Do not end the subject line with a period
5. Use the imperative mood in the subject line
6. Wrap the body at 72 characters
7. Use the body to explain what and why vs. how

Additionally, you can add a scope followed by a colon. Sometimes it may help clarify and shorten the message:

```
Decode: Fix regexp for numeric entities
--versus--
Fix the decode regexp for numeric entities
```

Remember to capitalize the subject again after the colon.

For a more detailed explanation please read the excellent article of [Chris Beams](https://github.com/cbeams) and the guide of WordPress VIP:

* [https://chris.beams.io/posts/git-commit](https://chris.beams.io/posts/git-commit/#seven-rules)
* [https://wpvip.com/documentation/commit-messages](https://wpvip.com/documentation/commit-messages/)

## Code comments

For code comments, we follow these guidelines:

1. Write your comments in plain, valid English.
2. Capitalize the first word and end with a period.
3. Use the imperative mood.
4. Break the line at 80 characters.
5. Use TSDoc for all the types, interfaces and functions.

### 1. Write your comments in plain, valid English

```javascript
// Bad comment. Too Cryptic. Please talk English.

// This is a good comment. It is not cryptic and it's easy to read.
// Please, talk in proper English, like when you talk to a person.
```

### 2. Capitalize the first word and end with a period

```javascript
// this is a bad comment

// Remember to capitalize the first word and end with a period.
```

### 3. Use the imperative mood

```javascript
/**
 * A function used to check if an email is valid.
 */
function validateEmail(...) { ... };

// Don't describe functions/types like this 👎


/**
 * Check if an email is valid.
 */
function validateEmail(...) { ... };

// This is much better 👍
```

### 4. Break the line at 80 characters

```javascript
// This is a bad comment because is longer than 80 characters and people need to scroll right to read it. Don't do this.

// This is a good comment. You can create different phrases. Then, break the
// line if it is too long so people do not have to scroll to the right to read
// everything.
```

There is a VS Code extension to do this automatically: <https://marketplace.visualstudio.com/items?itemName=stkb.rewrap>

### 5. Use TSDoc for all the types, interfaces and functions

```typescript
// Don't use regular comments for types, interfaces and functions.
function validateEmail(email: string): boolean {
  //...
}

/**
 * Use proper TSDoc.
 *
 * @params email - The email to be validated.
 *
 * @returns True if the email is valid and false otherwise.
 */
function validateEmail(email: string): boolean {
  //...
}
```

You can find more about TSDoc at the official repository: <https://github.com/microsoft/tsdoc>

## Coding Standards

Most of the coding standards are enforced by our `EsLint` and `Prettier` configuration. Please make sure you have both installed in your editor. For VS Code, the extensions are:

* <https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode>
* <https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint>

You don't need to configure anything, the default configuration is fine.

Apart from those, please pay attention to these other points:

1. Use `interface` over `type` whenever possible.
2. Use an `interface` when functions have object arguments.
3. Add a line break between TSDoc comments.

### 1. Use `interface` over `type` whenever possible

Use

```typescript
interface Something {
  // ...
}
```

Instead of

```typescript
type Something = {
  // ...
};
```

### 2. Use an `interface` when functions take an object as an argument or when functions return an object

Instead of typing the objects inline, use a separate interface to be able to document the object using TSDoc. Use the `@link` tag to link the interface and function together.

For functions that take an object as an argument use:

```typescript
/**
 * Options for the {@link validateEmail} function.
 */
interface ValidateEmailOptions {
  /**
   * Whether to allow dots in the email or not.
   *
   * @defaultValue true
   */
  allowDots: string;
}

/**
 * Validate an email address.
 *
 * @param email - The email address to be validated.
 * @param options - The options, defined in {@link ValidateEmailOptions}.
 *
 * @returns True if the email is valid, false otherwise.
 */
const validateEmail = (
  email: string,
  options: ValidateEmailOptions
): boolean => {
  // ...
};
```

Instead of:

```typescript
/**
 * Validate an email address.
 *
 * @param email - The email address to be validated.
 * @param options - The options.
 * @param options.allowDots - Whether to allow dots in the email or not.
 *
 * @returns True if the email is valid, false otherwise.
 */
const someFunction = (link: string, options: { prop1: string }): void => {
  // ...
};
```

For functions that return an object use:

```typescript
/**
 * Return object for the {@link validateEmail} function.
 */
interface ValidateEmailReturn {
  /**
   * The email address that was validated.
   */
  email: string;

  /**
   * True if the email was valid, false otherwise.
   */
  valid: boolean;
}

/**
 * Validate an email address.
 *
 * @param email - The email address to be validated.
 *
 * @returns Defined in {@link ValidateEmailReturn}.
 */
const validateEmail = (email: string): ValidateEmailReturn => {
  // ...
};
```

## Changelogs

We use [Changesets](https://github.com/atlassian/changesets/) to manage our versioning and changelogs.

### What is a changeset

A changeset is a piece of information about changes made in a branch or commit. It holds three bits of information:

* What we need to release.
* What version we are releasing packages at (using a [SemVer bump type](https://semver.org/)).
* A changelog entry for the released packages.

If you pull request has changes that need to be released in a new version of some of the packages, you need to include a changeset file in the pull request.

### How to create a changeset

1. Run the command-line script `npx changeset`.
2. Select the packages you want to include in the changeset using ↑ and ↓ to navigate to packages, and hit `space` to select a package. Hit `enter` when all desired packages are selected.
3. You will be prompted to select a bump type for each selected package. Select an appropriate bump type for the changes made. Those are:
   * **Major version**: when you make incompatible API changes.
   * **Minor version:** when you add functionality in a backward-compatible manner.
   * **Patch version:** when you make backward-compatible bugfixes. See [here](https://semver.org/) for information on SemVer versioning.
4. Your final prompt will be to provide a message to go alongside the changeset. This will be written into the changelog when the next release occurs.

After this, a new changeset file will be added, which is a Markdown file with Yaml front matter.

```
-| .changeset/
-|-| some-unique-name.md
```

#### **You can write as much Markdown as you want**

The message you typed can be found in the Markdown file. If you want to expand on it, you can write as much Markdown as you want, which will all be added to the changelog on publish. If you want to add more packages or change the bump types of any packages, that's also fine.

A good idea of what should be in a changeset is:

* **What** the change is.
* **Why** the change was made.
* **How** a consumer should update their code.

Once you are happy with the changeset, commit the file to your branch.

#### You can add more than one changeset to a pull request

Changesets are designed to stack, so there's no problem with adding multiple. You might want to add more than one changeset when:

* You want to release multiple packages with different changelog entries.
* You have made multiple changes to a package that should each be called out separately.

For more [detailed information on changesets please read their guide](https://github.com/atlassian/changesets/blob/master/docs/detailed-explanation.md).

{% hint style="info" %}
Still have questions? Ask [the community](https://community.frontity.org/)! We are here to help 😊
{% endhint %}


