# Introduction

⚠️ **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.**

***

## Introduction

Welcome to Frontity, and to the API Reference 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 (api.frontity.org) is where you will find detailed technical descriptions for the CLI, packages and plugins available in 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.

### Frontity CLI

In the [**CLI Commands**](/frontity-cli) section you'll find information about the commands provided by the Frontity CLI that you can use to create, run and build your Frontity projects.

### Packages

Frontity packages are the ingredients of your Frontity project. They're **NPM packages** in charge of a specific portion of logic required by the project (routing, source, HTML render... ).

You can learn all about the existing Frontity packages in the section entitled [**Frontity Packages**](/frontity-packages).

#### Themes Packages

Themes are just a special instance of a Frontity package. Really **everything** is a package when you're working with Frontity.

The official themes, namely `mars-theme` and `twentytwenty-theme`, are dealt with separately from the other packages under the [**Frontity Themes**](/frontity-packages/themes-packages) section.

### Plugins

Sometimes a **Frontity WordPress plugin** is required so everything works smoothly. You'll find everything you need to know about them in the [**WordPress Plugins**](/frontity-plugins) section.

{% 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 %}


# CLI Commands

API reference of Frontity CLI commands.

The Frontity command-line tool (CLI) is the main entry point for getting up and running with a Frontity application. It provides functionality like running a development server or building your Frontity application for deployment.

## How to use Frontity CLI

The Frontity CLI (Frontity commands) is available via [npm](https://www.npmjs.com/package/frontity). You can run any Frontity command by doing `npx frontity <frontity-command>`

Run `npx frontity --help` for full help.

## Commands

The `frontity` commands you have available are:

### [Create commands](/frontity-cli/create-commands)

These commands allow you to either create a Frontity project or a Frontity package:

* [`create`](/frontity-cli/create-commands/create)
* [`create-package`](/frontity-cli/create-commands/create-package)

### [Run commands](/frontity-cli/run-commands)

These commands allow you to run a Frontity project in development or production mode:

* [`dev`](/frontity-cli/run-commands/dev)
* [`serve`](/frontity-cli/run-commands/serve)

### [Build commands](/frontity-cli/build-commands)

These commands allow you to generate the code that can be used to run or analyze a Frontity project:

* [`build`](/frontity-cli/build-commands/build)

### [Extra commands](/frontity-cli/extra-commands)

* [`subscribe`](/frontity-cli/extra-commands#subscribe)
* [`info`](/frontity-cli/extra-commands#info)

{% hint style="info" %}
You can also use `--help` with each of these commands to get more information about them: `npx frontity dev --help`
{% endhint %}

{% hint style="info" %}
Have a look at [this video](https://www.youtube.com/watch?v=3d7b-cy5cFY) to learn more about what Frontity does internally when these commands are executed.
{% endhint %}

## Arguments & Environment Variables

The Frontity CLI allows parametrization via arguments or environment variables to customize their execution.

If some of these arguments or environment variables are detected the proper values will be set and applied in the execution of the command.

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

### `--no-prompt`

There's a **`--no-prompt`** option that can be used along with environment variables to avoid any questions from the CLI.

**Example**

If you pass the `--no-prompt` flag to the [`create`](/frontity-cli/create-commands/create) or [`create-package`](/frontity-cli/create-commands/create-package), the CLI will use the name from either [`FRONTITY_CREATE_NAME`](/frontity-cli/create-commands/create#frontity_create_name) or [`FRONTITY_CREATE_PACKAGE_NAME`](/frontity-cli/create-commands/create-package#frontity_create_package_name) environment variables.

If the CLI cannot find any of these environmental variables, it will prompt for the name of the package.

This is the scheme followed by the CLI to get the name of the package:

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

## A typical workflow with Frontity commands

### In development

1. Create a Frontity project: `npx frontity create my-cool-project`
2. Add a custom theme (package): `npx frontity create-package my-custom-theme`
3. Launch a development server: `npx frontity dev`

### In production

1. Generate a build of the project: `npx frontity build`
2. Launch the project in production using the build generated before: `npx frontity serve`


# Create commands

These commands will allow you to either create a Frontity project or a Frontity package

* [`create`](/frontity-cli/create-commands/create)
* [`create-package`](/frontity-cli/create-commands/create-package)


# create

## `create`

Creates a new Frontity project.

```
npx frontity create [project-name] [options]
```

### Arguments

#### `[project-name]`

The *name* of your Frontity project. It will also be the name of the folder that this command will create for you with the files of your Frontity project inside.

#### `[options]`

|                                   Option                                   | Description                                                                                                                                                |
| :------------------------------------------------------------------------: | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [`--theme <theme>`](/frontity-cli/create-commands/create#the-theme-option) | The theme to use                                                                                                                                           |
|                               `--typescript`                               | Adds support for TypeScript. Related environment variable: [`FRONTITY_CREATE_TYPESCRIPT`](/frontity-cli/create-commands/create#frontity_create_typescript) |
|                                 `--use-cwd`                                | Generates the project in the current directory                                                                                                             |
|                                 `--no-git`                                 | `frontity create` initializes by default a git repository. This option skips this initialization.                                                          |
|                                `--no-prompt`                               | Skips prompting the user for options. Related environment variable: [`FRONTITY_CREATE_NAME`](/frontity-cli/create-commands/create#frontity_create_name)    |
|                                  `--help`                                  | Output usage information                                                                                                                                   |

#### The `--theme` option

You can either pick one of the two official Frontity themes ([`--theme @frontity/mars-theme`](https://github.com/frontity/frontity/tree/dev/packages/mars-theme) or [`--theme @frontity/twentytwenty-theme`](https://github.com/frontity/frontity/tree/dev/packages/twentytwenty-theme)) or use any other custom theme as long as it's [published on npm](https://www.npmjs.com/search?q=keywords:frontity-theme). Just pass the theme name on the command-line like `--theme ThemesPackageNameInNPM`.

### Examples

* Create a Frontity project named `my-awesome-project`:

```
npx frontity create my-awesome-project
```

* Create a Frontity project named `my-awesome-project` using [Frontity Chakra theme](https://www.npmjs.com/package/frontity-chakra-theme):

```
npx frontity create --theme frontity-chakra-theme cool-project
```

* If you leave out both of the arguments, the CLI will run an interactive shell asking for these inputs:

```
> npx frontity create
...
? Enter a name for the project: awesome project
? Pick a starter theme to clone: @frontity/mars-theme (recommended)
✔ Creating README.md.
✔ Creating package.json.
✔ Creating frontity.settings.js.
✔ Cloning @frontity/mars-theme.
✔ Installing dependencies.
✔ Downloading favicon.ico.

Frontity project created.

? Do you want to receive framework updates by email? No

Ok, that's fine! 😉
You can subscribe at any point with npx frontity subscribe <email>.

Run cd awesome project && npx frontity dev and have fun! 🎉

You can find docs at https://docs.frontity.org/.
For technical support and assistance please join our community at https://community.frontity.org/.
```

## Environment Variables

### `FRONTITY_CREATE_NAME`

If you pass the [`--no-prompt`](/frontity-cli#no-prompt) flag to the `create` command, the CLI will use the name from this `FRONTITY_CREATE_NAME` environment variable.

If the CLI cannot find a `FRONTITY_CREATE_NAME` environmental variable, it will prompt for the name of the package.

*Example:*

```
FRONTITY_CREATE_NAME=test-project
```

{% hint style="info" %}
You can see a scheme of the whole workflow of using this `FRONTITY_CREATE_NAME` environment variable in the [`--no-prompt`](/frontity-cli#no-prompt) section.
{% endhint %}

### `FRONTITY_CREATE_TYPESCRIPT`

Adds support for TypeScript in the project created.

*Example:*

```
FRONTITY_CREATE_TYPESCRIPT=true
```


# create-package

The `create-package` command creates a new Frontity package in a project. Launch this command from the root of the Frontity project

```
npx frontity create-package [package-name] [options]
```

## Arguments

### **`[package-name]`**

This argument sets the *name* of your Frontity package. The `create-package` command will create a folder named `[package-name]` under `packages`. It will also add the proper dependency in the `package.json` of your Frontity project

### **`[options]`**

|         Option        | Description                                                                                                                                                                      |
| :-------------------: | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--namespace <value>` | Sets the [namespace](https://docs.frontity.org/learning-frontity/namespaces) for this package                                                                                    |
|     `--no-prompt`     | Skips prompting the user for options. Related environment variable: [`FRONTITY_CREATE_PACKAGE_NAME`](/frontity-cli/create-commands/create-package#frontity_create_package_name). |
|        `--open`       | Output usage information                                                                                                                                                         |

## Examples

* Create a custom theme package named `my-custom-project`

```
>  npx frontity create-package my-custom-theme
? Enter the namespace of the package: theme
✔ Adding package.json.
✔ Adding src/index.js.
✔ Installing package my-custom-theme.

New package "my-custom-theme" created.
```

## Environment Variables

### `FRONTITY_CREATE_PACKAGE_NAME`

If you pass the [`--no-prompt`](/frontity-cli#no-prompt) flag to the [`create-package`](/frontity-cli/create-commands/create-package), the CLI will use the name from this `FRONTITY_CREATE_PACKAGE_NAME` environment variable.

If the CLI cannot find a `FRONTITY_CREATE_PACKAGE_NAME` environmental variable, it will prompt for the name of the package

*Example:*

```
FRONTITY_CREATE_NAME=test-project
```

{% hint style="info" %}
You can see a scheme of the whole workflow of using this `FRONTITY_CREATE_PACKAGE_NAME` environment variable in the [`--no-prompt`](/frontity-cli#no-prompt) section
{% endhint %}


# Run commands

These commands will allow you to run a Frontity project in development or production mode

* [`dev`](/frontity-cli/run-commands/dev)
* [`serve`](/frontity-cli/run-commands/serve)


# dev

Starts a development server.

```
npx frontity dev [options]
```

## Arguments

### **`[options]`**

|                                       Option                                       | Description                                                                                                                                                                                                                           |
| :--------------------------------------------------------------------------------: | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|       [`--production`](/frontity-cli/run-commands/dev#the-production-option)       | Builds the project for production. Related environment variable: [`FRONTITY_DEV_PRODUCTION`](/frontity-cli/run-commands/dev#frontity_dev_production)                                                                                  |
|                                   `--port <port>`                                  | Runs the server on a custom port. Default is 3000. Related environment variable: [`FRONTITY_DEV_PORT`](/frontity-cli/run-commands/dev#frontity_dev_port)                                                                              |
|                                      `--https`                                     | Runs the server using https. Related environment variable: [`FRONTITY_DEV_HTTPS`](/frontity-cli/run-commands/dev#frontity_dev_https)                                                                                                  |
|                                `--dont-open-browser`                               | Don't open a browser window with the localhost. Related environment variable: [`FRONTITY_DEV_DONT_OPEN_BROWSER`](/frontity-cli/run-commands/dev#frontity_dev_dont_open_browser)                                                       |
|     [`--target <target>`](/frontity-cli/build-commands/build#the-target-option)    | Create bundles with `es5` or `module`. Default target is `module`. Related environment variable: [`FRONTITY_DEV_TARGET`](/frontity-cli/run-commands/dev#frontity_dev_target)                                                          |
| [`--publicPath <path>`](/frontity-cli/build-commands/build#the-public-path-option) | Set the [public path](https://webpack.js.org/guides/public-path/) for static assets. Default path is `/static/`. Related environment variable: [`FRONTITY_DEV_PUBLIC_PATH`](/frontity-cli/run-commands/dev#frontity_dev_public_path). |
|                                      `--help`                                      | Output usage information                                                                                                                                                                                                              |

**Examples**

* Starts a server in development mode using https and port 3002

```
npx frontity dev --https --port 3002
```

* Starts a server in development mode using the folder `assets` as the path for statics

```
npx frontity dev --public-path="/assets"
```

### The `--production` option

This flag correspond to [webpack’s mode parameter](https://webpack.js.org/configuration/mode/) so it will run webpack in the production mode as described [there](https://webpack.js.org/configuration/mode/) before launching the development server.

So, if you do:

```
npx frontity dev --production
```

The webpack bundler internally will do things like..

* Enable certain webpack-specific optimizations and minify the code
* Also disable hot-module reloading (HMR)
* Not create source maps
* Append hashes to filenames so for caching purposes

Normally, you would always use the development server in development mode, but sometimes you may want to check that everything works in production mode, or check the bundle analyzer (the files at `/build/analyze`) for the production bundle.

## Environment Variables

### `FRONTITY_DEV_TARGET`

Create bundles with `es5`, `module` or `both`. Default target is `both`.

If detected, and no `--target <target>` option is defined for [`dev`](/frontity-cli/run-commands/dev#dev) Frontity command, this environment variable value will be applied.

*Example:*

```
FRONTITY_DEV_TARGET=module
FRONTITY_DEV_TARGET=es
```

### `FRONTITY_DEV_PORT`

Runs the server on a custom port. Default is `3000`.

If detected, and no `--port <port>` option is defined for [`dev`](/frontity-cli/run-commands/dev#dev) Frontity command, this environment variable value will be applied.

*Example:*

```
FRONTITY_DEV_PORT=3002
```

### `FRONTITY_DEV_HTTPS`

Runs the server using https.

*Example:*

```
FRONTITY_DEV_HTTPS=true
```

### `FRONTITY_DEV_PRODUCTION`

`frontity dev` by default runs the server in "development mode" (no optimizations, uses the dev build of react, etc.). Setting this variable makes it run in "production mode".

*Example:*

```
FRONTITY_DEV_PRODUCTION=true
```

### `FRONTITY_DEV_PUBLIC_PATH`

Set the public path for static assets. Default path is `/static/`.

If detected, and no `--public-path` flag is defined for [`dev`](/frontity-cli/run-commands/dev#dev) Frontity command, this environment variable value will be applied.

*Example:*

```
FRONTITY_DEV_PUBLIC_PATH=/assets/
```

### `FRONTITY_DEV_DONT_OPEN_BROWSER`

Don't open a browser window after the Frontity server has been started.

*Example:*

```
FRONTITY_DEV_DONT_OPEN_BROWSER=true
```


# serve

Starts a Frontity server in production mode.

```
npx frontity serve [options]
```

This `frontity serve` command will use the files generated by [`frontity build`](/frontity-cli/build-commands/build)

## Arguments

### **`[options]`**

|      Option     | Description                                                                                                                                                    |
| :-------------: | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--port <port>` | Runs the server on a custom port. Default is 3000. Related environment variable: [`FRONTITY_SERVE_PORT`](/frontity-cli/run-commands/serve#frontity_serve_port) |
|    `--https`    | Runs the server using https. Related environment variable: [`FRONTITY_SERVE_HTTPS`](/frontity-cli/run-commands/serve#frontity_serve_https)                     |
|     `--help`    | Output usage information                                                                                                                                       |

**Examples**

* Starts a server (using the code in the `build` folder generated by the `npx frontity build` command) using https and port 3002

```
npx frontity serve --https --port 3002
```

## Environment Variables

### `FRONTITY_SERVE_PORT`

Runs the server on a custom port. Default is `3000`.

If detected, and no `--port <port>` option is defined for [`serve`](/frontity-cli/run-commands/serve#serve) Frontity command, this environment variable value will be applied.

*Example:*

```
FRONTITY_SERVE_PORT=3002
```

### `FRONTITY_SERVE_HTTPS`

Runs the server using https.

*Example:*

```
FRONTITY_SERVE_HTTPS=true
```


# Build commands

These commands will allow you to generate the code that can be used to run or analyze a Frontity project

* [`build`](/frontity-cli/build-commands/build)

## The build process

When you do [`npx frontity build`](/frontity-cli/build-commands/build) you generate a `build` folder with several files.

You'll get something similar to this:

```
├── build
│   ├── analyze
│   │   ├── module-development.html
│   │   └── server-development.html
│   ├── bundling
│   │   ├── chunks.module.json
│   │   └── entry-points
│   │       ├── server.ts
│   │       └── my-frontity-project
│   │           └── client.ts
│   ├── server.js
│   └── static
           ...
│       ├── xxxxx1.module.js
│       ├── xxxxx2.module.js
```

The most important file for deployments in any hosting is `server.js`, which is actually a middleware that can be *inserted* in a custom web server.

### How to execute a Frontity project in production after the build

#### `npx frontity serve`

You can directly execute this `server.js` by using the command [`npx frontity serve`](/frontity-cli/run-commands/serve).

So, easy way of executing a Frontity project in any Node.js server:

* Launch remotely `npx frontity build` to generate the `build` folder.
* Launch remotely `npx frontity serve` to launch a web server that makes use of the `server.js` generated in the previous step.

#### Using `server.js` as a middleware

You can also use this generated `server.js` as part of a custom server like it's mentioned [here](https://community.frontity.org/t/deploy-to-aws-lambda/814/8).

```
// lambda.js
const awsServerlessExpress = require("aws-serverless-express");
const app = require("./build/server.js").default;
const server = awsServerlessExpress.createServer(app);

exports.handler = (event, context) => {
  awsServerlessExpress.proxy(server, event, context);
};
```

### The bundle analyzer

Frontity generates some reports automatically by using [Webpack Bundle Analyzer](https://github.com/webpack-contrib/webpack-bundle-analyzer).

When doing `npx frontity build` you get a `build` folder in the root of your project.

```
├── build
│   ├── analyze
│   │   ├── module-development.html
│   │   └── server-development.html
│   ├── bundling
│   │   ├── chunks.module.json
│   │   └── entry-points
│   │       ├── my-frontity-project
│   │       │   └── client.ts
│   │       └── server.ts
│   ├── server.js
│   └── static
│       ├── my-frontity-project.module.js
│       └── list.module.js
```

Inside that `build` folder there is a `.html` file generated at `analyze/module-development.html`. This file is a visual report in the form of a tree generated by [Webpack Bundle Analyzer](https://github.com/webpack-contrib/webpack-bundle-analyzer).

![](https://frontity.org/wp-content/uploads/2021/04/bundle-analyzer.gif)

This report shows you the modules included on each bundle and the size of each one, so that you can analyze them and maybe decide using other modules (or not including a specific module at all) to reduce the size of the final bundle.


# build

Builds the project for production.

```
npx frontity build [options]
```

The [`frontity serve`](/frontity-cli/run-commands/serve) command will use the files generated by this `frontity build` command.

## Arguments

### **`[options]`**

| Option                                                                       | Description                                                                                                                                                                                                                                  |
| ---------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [`--development`](/frontity-cli/build-commands/build#the-development-option) | Builds the project for development. Related environment variable: [`FRONTITY_BUILD_DEVELOPMENT`](/frontity-cli/build-commands/build#frontity_build_development)                                                                              |
| [`--target`](/frontity-cli/build-commands/build#the-target-option)           | Builds the project. Create bundles with "es5", "module" or "both". Default target is "both". Related environment variable: [`FRONTITY_BUILD_TARGET`](/frontity-cli/build-commands/build#frontity_build_target)                               |
| [`--publicPath`](/frontity-cli/build-commands/build#the-public-path-option)  | Set the [public path](https://webpack.js.org/guides/public-path/) for static assets. Default path is "/static/". Related environment variable: [`FRONTITY_BUILD_PUBLIC_PATH`](/frontity-cli/build-commands/build#frontity_build_public_path) |
| `--help`                                                                     | Output usage information                                                                                                                                                                                                                     |

**Examples**

* Builds the project for production using an external domain `https://external-domain.com/static` as the path for static files

```
npx frontity build --public-path="https://external-domain.com/static"
```

### The `--development` option

This flag correspond to [webpack’s mode parameter](https://webpack.js.org/configuration/mode/) so it will run webpack in the development mode as described [there](https://webpack.js.org/configuration/mode/).

For example, when running react in development mode (when `process.env.NODE_ENV` is set to `development` and NOT to `production`) you get [full error messages and warnings](https://reactjs.org/docs/optimizing-performance.html#use-the-production-build) from React but at the cost of slower performance.

```
npx frontity build --development
```

So, it’s basically the same as just running `frontity dev` except that it will only build the project `once` and will **not run the development server**.

### The `--target` option

The target option allows to decide what features will be transpiled with babel.

With `--target es5`, the support of the following browsers as the minimum is:

```
es5: {
    browsers: [
      "and_chr >= 67",
      "and_ff >= 18",
      "and_uc >= 11.8",
      "android >= 67",
      "not android <= 4.4.4",
      "chrome >= 49",
      "edge >= 12",
      "firefox >= 18",
      "ios_saf >= 10",
      "not op_mini all",
      "op_mob >= 46",
      "opera >= 36",
      "safari >= 10",
      "samsung >= 5",
    ],
  },
```

So, Frontity **don't** transpile any features that those browsers already support. In particular Frontity aim to support only the browsers that ship with the [built-in `Proxy` object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy) . This list comes from [here](https://github.com/frontity/frontity/blob/107d3543ce5463186809b7e6f50ca31ffbdc107d/packages/core/src/config/babel/index.ts#L20-L37) and it is [used by the @babel/preset-env](https://babeljs.io/docs/en/babel-preset-env#targets) to determine how to transpile the files.

With `--target module`, Frontity tell babel to [only support the browsers that support ESModules](https://babeljs.io/docs/en/babel-preset-env#targetsesmodules)

### The `--public-path` option

By default Frontity will look for static assets in the path `<YOUR-DOMAIN>/static`

With the `--public-path` option you can change the path from where you are serving the statics assets (i.e. js chunk files, fonts, images, etc.)

The [public path is included in the generated files by webpack](https://webpack.js.org/guides/public-path/) and cannot be changed after that.

In case some people need to change it (because of constrains in their site architecture) they would need an option to do so just before generating the Frontity bundle with `npx frontity build`.

{% hint style="info" %}
This option is also available for [`dev`](/frontity-cli/run-commands/dev) command
{% endhint %}

*Example:*

```
npx frontity build --public-path="/other/folder"
```

## Environment Variables

### `FRONTITY_BUILD_TARGET`

Create bundles with `es5`, `module` or `both`. Default target is `both`.

If detected, and no `--target` option is defined for [`build`](/frontity-cli/build-commands/build#build) Frontity command, this environment variable will be applied.

*Example:*

```
FRONTITY_BUILD_TARGET=module
FRONTITY_BUILD_TARGET=es
```

### `FRONTITY_BUILD_DEVELOPMENT`

Frontity by default builds the server in "production mode". Setting this variable makes it run in "development mode" (with disabled optimizations, etc.)

*Example:*

```
FRONTITY_BUILD_DEVELOPMENT=true
```

### `FRONTITY_BUILD_PUBLIC_PATH`

Set the public path for static assets. Default path is `/static/`.

If detected, and no [`--public-path`](/frontity-cli/build-commands/build#the-publicpath-option) flag is defined for [`build`](/frontity-cli/build-commands/build#build) Frontity command, this environment variable value will be applied.

*Example:*

```
FRONTITY_BUILD_PUBLIC_PATH=/assets/
```


# Extra commands

* [`info`](/frontity-cli/extra-commands#info)
* [`subscribe`](/frontity-cli/extra-commands#info)

## Info

Gets environment information for debugging and issue reporting.

```
npx frontity info [options]
```

### Arguments

#### **`[options]`**

|  Option  | Description              |
| :------: | ------------------------ |
| `--help` | Output usage information |

### Examples

* Display information about my specific environment.

> When you ask in the [community forum](https://community.frontity.org/) about an issue you're having in development mode, it is very helpful to share this information so the community can check things like OS, Node version, etc.

```
> npx frontity info
...

## System:
 - OS: macOS Mojave 10.14.6
 - CPU: (4) x64 Intel(R) Core(TM) i7-7660U CPU @ 2.50GHz
 - Memory: 879.63 MB / 16.00 GB
 - Shell: 5.3 - /bin/zsh
## Binaries:
 - Node: 10.15.3 - /usr/local/bin/node
 - npm: 6.13.1 - /usr/local/bin/npm
## Browsers:
 - Chrome: 81.0.4044.138
 - Edge: Not Found
 - Firefox: 68.8.0
 - Safari: 13.1
## npmGlobalPackages:
 - frontity: Not Found
 - npx: Not Found


  System info copied in the clipboard!
  You can now paste it in the Frontity Community or GitHub issue.
```

## Subscribe

Subscribes to the Frontity newsletter.

```
npx frontity subscribe [options] [email]
```

### Arguments

#### **`[options]`**

|  Option  | Description              |
| :------: | ------------------------ |
| `--help` | Output usage information |

#### **`[email]`**

The Frontity newsletter will be sent to this *email* address.


# Packages

API reference of Frontity and its packages.

Frontity projects are built around the idea of packages that encapsulate logic that can be reused across projects. Frontity packages may be considered as the equivalent of WordPress plugins. They're the ingredients of the final Frontity project.

## How to use Frontity packages

Frontity packages are available via [npm](https://www.npmjs.com/search?q=keywords:frontity) and they can be installed as dependencies of your Frontity project (as with any other Node project).

Frontity needs to know the packages we're going to use in the project and how we want to use them. We can set this in the `frontity.settings.js` file, where we can define and configure the packages (by using Namespaces) for the Frontity project.

{% hint style="info" %}
We're going to focus on the use of Frontity packages at a Frontity project level, but the same applies if you're creating a custom Frontity package. You can see more info about how to create your custom package [here](/frontity-cli/create-commands/create-package).
{% endhint %}

## Official Frontity Packages

The official Frontity packages are those created and maintained by the [Frontity Team](https://frontity.org/about-us/).

These packages encapsulate the logic to apply the main features needed in a WordPress + React stack project managed by Frontity.

A Frontity project is basically the sum of the **Core package** plus a selection of **Features packages**. You can also use **Collections packages** to help speed up the development of your Frontity project.

{% hint style="info" %}
The [full list of packages](https://www.npmjs.com/search?q=keywords:frontity) includes others created by the community, such as [these themes](/frontity-packages/themes-packages#community-themes) and [these features packages](/frontity-packages/features-packages#community-packages). However, only the official `frontity` packages that have a public API are fully documented here.
{% endhint %}

### 💙 [Core package](/frontity-packages/core-package)

This package is the core of the Frontity framework and provides the main utilities of the framework.

* [`frontity`](/frontity-packages/core-package/frontity)

### 🎨 [Themes packages](/frontity-packages/themes-packages)

These packages contain the React project used to render the final output (both in client and server side).

* [`@frontity/mars-theme`](/frontity-packages/themes-packages/frontity-mars-theme)
* [`@frontity/twentytwenty-theme`](/frontity-packages/themes-packages/frontity-twentytwenty-theme)

### ⚡️ [Features packages](/frontity-packages/features-packages)

#### Source package

This package is in charge of getting data from WordPress and make it accesible from React components.

* [`@frontity/wp-source`](/frontity-packages/features-packages/wp-source)

#### Router package

This package is in charge of managing (React) routes in a Frontity project.

* [`@frontity/tiny-router`](/frontity-packages/features-packages/tiny-router)

#### Render package

This package is in charge of converting HTML to React.

* [`@frontity/html2react`](/frontity-packages/features-packages/html2react)

#### SEO packages

These packages are designed to get automatically all the data from WordPress SEO plugins and render it (along with the content) in the final HTML.

* [`@frontity/head-tags`](/frontity-packages/features-packages/head-tags)
* [`@frontity/yoast`](/frontity-packages/features-packages/yoast)

#### Ads packages

These packages allow you to insert ads in your Frontity projects from services such as Google Ad Manager.

* [`@frontity/google-ad-manager`](/frontity-packages/features-packages/google-ad-manager)
* [`@frontity/smart-adserver`](/frontity-packages/features-packages/smart-ads)

#### Analytics packages

A set of official Analytics Frontity packages that you can use to easily add analytics services to your project.

* [`@frontity/google-analytics`](/frontity-packages/features-packages/analytics/google-analytics)
* [`@frontity/google-tag-manager-analytics`](/frontity-packages/features-packages/analytics/google-tag-manager-analytics)
* [`@frontity/comscore-analytics`](/frontity-packages/features-packages/analytics/comscore-analytics)

#### Comments packages

This package adds support for WordPress' native comments.

* [`@frontity/wp-comments`](/frontity-packages/features-packages/wp-comments)

### 📚 Collections packages

These packages are collections of useful components or hooks that you can use in your Frontity project.

* [`@frontity/components`](/frontity-packages/collections-packages/components)
* [`@frontity/hooks`](/frontity-packages/collections-packages/hooks)


# Core package

The core `frontity` package is the heart of the Frontity framework.

Besides containing the Frontity CLI commands (`npx frontity <command>`), the package is an entry point for other packages and utils, so it exposes the key methods and components provided by the Framework

* [`frontity`](/frontity-packages/core-package/frontity)


# frontity

API reference of \`frontity\` package

Apart from being the package that executes the Frontity commands in the terminal, `frontity` also exports functions, objects, etc. to be imported and used by other Frontity packages.

You can import any of these utils using:

```javascript
import { connect, styled, Head, ... } from "frontity";
```

## Table of Contents

* [Overview](/frontity-packages/core-package/frontity#overview)
  * [React](/frontity-packages/core-package/frontity#react)
  * [CSS in JS](/frontity-packages/core-package/frontity#css-in-js)
  * [Code Splitting](/frontity-packages/core-package/frontity#code-splitting)
  * [`fetch` and `URL`](/frontity-packages/core-package/frontity#fetch-and-url)
* [API Reference](/frontity-packages/core-package/frontity#api-reference)
  * [`connect`](/frontity-packages/core-package/frontity#connect)
  * [`useConnect`](/frontity-packages/core-package/frontity#useconnect)
  * [`styled`](/frontity-packages/core-package/frontity#styled)
  * [`css`](/frontity-packages/core-package/frontity#css)
  * [`Global`](/frontity-packages/core-package/frontity#global)
  * [`keyframes`](/frontity-packages/core-package/frontity#keyframes)
  * [`loadable`](/frontity-packages/core-package/frontity#loadable)
  * [`Head`](/frontity-packages/core-package/frontity#head)
  * [`useFills`](/frontity-packages/core-package/frontity#usefills)
  * [`fetch`](/frontity-packages/core-package/frontity#fetch)
  * [`URL`](/frontity-packages/core-package/frontity#url)
  * [`error` & `warn`](/frontity-packages/core-package/frontity#error-and-warn)
    * [`error`](/frontity-packages/core-package/frontity#error)
    * [`warn`](/frontity-packages/core-package/frontity#warn)
  * [`decode`](/frontity-packages/core-package/frontity#decode)
  * [`Slot`](/frontity-packages/core-package/frontity#slot)

## Overview

### React

Use [**`connect`**](/frontity-packages/core-package/frontity#connect) to inject `state`, `actions` and `libraries` in your React components.

If you are familiar with React hooks, you can use also [**`useConnect`**](/frontity-packages/core-package/frontity#useconnect) to do the same.

Use the [**`Head`**](/frontity-packages/core-package/frontity#head) component whenever you want to add HTML tags inside the `<head>` of any of your site's pages. You can read more in the [Head page](https://docs.frontity.org/learning-frontity/head) of the **Core Concepts** section.

Use the [**`Slot`**](/frontity-packages/core-package/frontity#slot) component whenever you want to add a 'placeholder' to your theme which will be filled with a **`Fill`**. Fills are added to the state in the `state.fills` namespace.

### CSS in JS

[**`styled`**](/frontity-packages/core-package/frontity#styled) creates new React components from HTML tags, or other React components, with styles attached to them. [**`css`**](/frontity-packages/core-package/frontity#css) lets you to add inline styles to an element if you don't want to create a new component. If you want to add styles for the whole app, use [**`Global`**](/frontity-packages/core-package/frontity#global). And [**`keyframes`**](/frontity-packages/core-package/frontity#keyframes) is used to define and use animations in your CSS.

You can read more in the [Styles](https://docs.frontity.org/learning-frontity/styles) page of the **Core Concepts** section of the docs.

### Code Splitting

Use [**`loadable`**](/frontity-packages/core-package/frontity#loadable) in order to separate you code into different bundles that will be dynamically loaded at runtime. This helps you to reduce your page size.

You can read more in this [Code Splitting](https://docs.frontity.org/performance/code-splitting) page of the docs.

### `fetch` and `URL`

Frontity exports [`fetch`](/frontity-packages/core-package/frontity#fetch) and [`URL`](/frontity-packages/core-package/frontity#url) with the same API they have in the browser, but they work the same both in the client and in the server.

## API Reference

### `connect`

It's a function that receives a React component and returns the same component but connected to the Frontity state, actions and libraries. Any instance of that component will receive three new props: `state`, `actions` and `libraries`, allowing the component to read the state, manipulate it through actions or use any code other packages have exposed in libraries.

Also, that instance will re-render automatically whenever any value from the `state` which the component is using is changed.

If you don't want to inject the Frontity state props in your connected components, you can use the `injectProps` option set to `false`. Components will still be reactive to changes in the state but without receiving more props.

For these components to access the state use the [`useConnect`](/frontity-packages/core-package/frontity#useconnect) hook.

#### Syntax

```javascript
ConnectedComponent = connect(Component, options?);
```

#### Arguments

| Name              | Object Property | Type            | Required | Description                                                                                                     |   |
| ----------------- | --------------- | --------------- | -------- | --------------------------------------------------------------------------------------------------------------- | - |
| ***`Component`*** |                 | React component | yes      | Link representing a REST API endpoint or custom handler                                                         |   |
| *`options`*       |                 | object          | no       | options object                                                                                                  |   |
| *`options`*       | `injectProps`   | boolean         | -        | If `false`, the `state`, `actions` and `libraries` won't be passed as props to the component. Default is `true` |   |

#### Return value

* The same component as passed in as the first argument but connected to the Frontity state

#### Example

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

```jsx
import React from "react";
import { connect } from "frontity";
import { Loading, List, Post, PageError } from "./components";

const Page = ({ state }) => {
  // The next line will trigger a re-render whenever
  // the value of "state.router.link" changes.
  const data = state.source.get(state.router.link);

  return (
    <Switch>
      <Loading when={data.isFetching} />
      <List when={data.isArchive} />
      <Post when={data.isPostType} />
      <PageError when={data.isError} />
    </Switch>
  );
};

// Connect Page to the Frontity state.
export default connect(Page);
```

{% endcode %}

### `useConnect`

It's a React hook that returns the Frontity state, allowing the component to consume `state`, `actions` and `libraries` in components without passing them as props.

{% hint style="warning" %}
You still need to use [`connect`](/frontity-packages/core-package/frontity#connect) when using `useConnect` properly.

By using `connect`:

* Your components get optimized with *memo*, so they won't re-render whenever a parent component re-renders
* Your components get reactive, so they will re-render when the parts of state they use are changed
  {% endhint %}

#### Syntax

```javascript
const { state, actions, libraries } = useConnect();
```

#### Return value

* The Frontity state (`state`, `actions` and `libraries`)

#### Example

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

```jsx
import React from "react";
import { connect, useConnect } from "frontity";
import { Loading, List, Post, PageError } from "./components";

const Page = () => {
  // Get state using useConnect hook.
  const { state } = useConnect();

  // The next line will trigger a re-render whenever
  // the value of "state.router.link" changes.
  const data = state.source.get(state.router.link);

  return (
    <Switch>
      <Loading when={data.isFetching} />
      <List when={data.isArchive} />
      <Post when={data.isPostType} />
      <PageError when={data.isError} />
    </Switch>
  );
};

// Connect Page to the Frontity state.
export default connect(Page);
```

{% endcode %}

#### Use Case of `{ injectProps: false }` with `connect`

Most of the times you'll use `useConnect` in this way:

```jsx
const Input = ({ name, type }) => {
  const { state } = useConnect();
  // Do something with `state`.

  return <input name={name} type={type} />;
};

export default connect(Input);
```

But if you want to pass down props to a HTML tag, like in this case:

```jsx
const Input = ({ name, type, ...props }) => {
  const { state } = useConnect();
  // Do something with `state`.

  return <input name={name} type={type} {...props} />;
};

export default connect(Input);
```

You'll end up passing `actions` and `libraries` to `<input>` as well, because they are injected by `connect`.

To avoid this you can:

* Add `{ injectProps: false }` to `connect`
* Use `const { state, actions, libraries } = useConnect();`

```jsx
const Input = (props) => {
  const { state } = useConnect();
  // Do something with `state` (or `actions` and `libraries`).

  return <input {...props} />;
};

// Avoid injecting `state`, `actions` and `libraries` so they are not present in `...props`.
export default connect(Input, { injectProps: false });
```

### `styled`

`styled` is a function that receives an HTML tag or a React component as the argument and returns a function that can be used as a [tagged template literal](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals#Tagged_templates). Inside, you write the CSS code for your component.

The `styled` tag function returns a styled component with the CSS you wrote.

Also, `styled` has built-in tag functions for every HTML tag so in those cases it is not necessary to call `styled` directly.

#### Syntax

```jsx
// You can use an HTML tag like this.
const StyledDiv = styled.div`
  font-size: 24px;
`;

// Or use it like a function and pass a React component.
const StyledComponent = styled(Component)`
  background: aliceblue;
`;
```

#### Arguments

* A template literal containing CSS code

#### Return value

* A React component with the styles defined

#### Example

```jsx
import { styled } from "frontity";
import { Page } from "./page";

const Main = () => (
  <Container>
    <StyledPage background="aliceblue" />
  </Container>
);

const Container = styled.div`
  display: flex;
  justify-content: center;
`;

const StyledPage = styled(Page)`
  background: ${(props) => props.background};
`;
```

### `css`

It's a tagged template literal to add an inline style to React Components.

The usage is quite similar to **`styled`** except that **`css`** doesn't return a React Component but a special object that can be passed to a component through the **`css`** prop.

#### Syntax

```javascript
const styleObject = css`
  background: pink;
`;
```

#### Arguments

* A template literal containing CSS code

#### Return value

* A style object to be passed to a **`css`** prop or to the **`<Global>`**'s **`styles`** prop

#### Example

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

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

### `Global`

It's a React component that creates global styles for the whole Frontity site.

{% hint style="warning" %}
**Using `<Global>` for 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 %}

#### Syntax

```jsx
<Global styles={styleObject} />
```

#### Props

* **`styles`**: an style object created with [`css`](/frontity-packages/core-package/frontity#css)

#### Example

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

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

### `keyframes`

It's a function used to define and use animations in your CSS.

#### Syntax

```jsx
const animation = keyframes`
    from { ... } to { ... };
`;
```

#### Arguments

* A template literal containing [CSS @keyframes](https://developer.mozilla.org/en-US/docs/Web/CSS/@keyframes) code

#### Return value

* An animation object to be used inside a template literal passed to [`styled`](/frontity-packages/core-package/frontity#styled) or [`css`](/frontity-packages/core-package/frontity#css)

#### Example

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

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

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

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

### `loadable`

It's a function that loads a component asynchronously generating a different bundle for it. Frontity has integrated and configured [Loadable Components](https://www.smooth-code.com/open-source/loadable-components/docs/code-splitting/), in case you want to check its docs.

You can also take a look at the [Code Splitting](https://docs.frontity.org/performance/code-splitting) page of the docs.

#### Syntax

```jsx
const HeavyComponent = loadable(importFunction, options);
```

#### Arguments

| Name                 | Object Property | Type            | Required | Description                                                                                                                                                                                                   |
| -------------------- | --------------- | --------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ***importFunction*** |                 | function        | yes      | a function that executes a [dynamic import](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import#Dynamic_Import) and returns a `Promise` that will contain the imported module |
| *`options`*          |                 | object          | no       | options object                                                                                                                                                                                                |
| *`options`*          | `fallback`      | React component | -        | component displayed until the `Promise` resolves                                                                                                                                                              |
| *`options`*          | `ssr`           | boolaan         | -        | if `false`, it will not be processed server-side (default to `true`)                                                                                                                                          |

#### Return value

* A React component

#### Example

```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);
```

### `Head`

#### Syntax

```jsx
<Head>{children}</Head>
```

It's a React component that injects their children in the HTML `<head>` tag. It allows you to change the title while navigating, add meta tags, scripts, etc.

As we use `react-helmet` under the hood, you may check its [reference guide](https://github.com/nfl/react-helmet#reference-guide).

#### Props

* **`children`**: the HTML tags you want to appear inside `<head>`

#### Example

```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>
);
```

### `useFills`

A React hook to ease the creation of `Slot` components.

#### Syntax

```javascript
const fills = useFills("Slot Name");
```

#### Arguments

| Name           | Type   | Required | Description                                   |
| -------------- | ------ | -------- | --------------------------------------------- |
| ***slotName*** | string | yes      | A string that refers to the name of the Slot. |

#### Return value

`Fill[]`

An array of configuration objects for the fills that want to fill the slot passed by the `slotName` parameter. The values in those objects will come from the fills defined by the user of the slot in `state.fills`.

Mind that a user might define more than one fill for a particular slot. Because of this, we always return a list of slots sorted in **ascending order** by their `priority`.

Each configuration object has this structure:

| Name           | Type           | Description                                                                                                                                                                                                          |
| -------------- | -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`Fill`**     | ReactComponent | The component that should be rendered for this fill.                                                                                                                                                                 |
| **`slot`**     | string         | The name of the slot. Mind that a user can define multiple fills that fill the same slot, so there might exist more than one object with the same `slot` property. Defined in `state.fills.namespace.fillName.slot`. |
| **`props`**    | object         | The props that should be passed down to the component. Defined in `state.fills.namespace.fillName.props`.                                                                                                            |
| **`library`**  | string         | The name of the library that is using the fill. defined in `state.fills.namespace.fillName.library`.                                                                                                                 |
| **`priority`** | number         | The priority of the fill. By default, the fills are sorted in ascending order according to this value. Defined in `state.fills.namespace.fillName.priority`.                                                         |
| **`key`**      | string         | This is a unique value that identifies the particular fill. It's a combination of the `namespace` and the `fillName`.                                                                                                |

#### Example

Import the hook in your React component and use it to create a component:

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

const Comp = () => {
  const fills = useFills("slot 1");

  return (
    <>
      {fills.map(({ Fill, props, key }) => (
        <Fill key={key} {...props} />
      ))}
    </>
  );
};

export default connect(Comp);
```

{% hint style="info" %}
You need to wrap the component that uses the `useFills` hook with `connect()` in order for that component to work.
{% endhint %}

#### Debug mode

If you want to see all the slots added to a theme/package without having to add fills for all of them, you can turn the debug mode on:

```javascript
state.frontity.debug = true;
```

If you want to do this on the console, remember that you need to access the `state` using `frontity.state`, like this:

![Debug mode in the console](https://frontity.org/wp-content/uploads/2021/04/frontity-debug-in-console.png)

### `fetch`

It's a function with the [WHATWG API](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch) for fetching a resource from the network.

This function is safe to use both server and client-side, but you have to import it first.

#### Syntax

```javascript
const fetchResponsePromise = fetch(resource, init);
```

#### Arguments

| Name           | Type   | Required | Description                                                                                                                                                                                                                                         |
| -------------- | ------ | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ***resource*** | string | yes      | a string containing the direct URL of the resource you want to fetch                                                                                                                                                                                |
| *`init`*       | object | no       | an options object containing any custom settings that you want to apply to the request (go to [this link](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch#Parameters) for the complete list of available settings) |

#### Return value

* A `Promise` that resolves to a [`Response`](https://developer.mozilla.org/en-US/docs/Web/API/Response) object

#### Example

```javascript
import { fetch } from "frontity";

const getFromSomeAPI = async (resource) => {
  const response = await fetch("https://site.com/api/v1" + resource);
  const body = await response.json();
  return body;
};
```

### `URL`

#### Syntax

```javascript
const url = new URL(url, base);
```

It's a constructor with the [WHATWG API](https://developer.mozilla.org/en-US/docs/Web/API/URL/URL) to create [`URL`](https://developer.mozilla.org/en-US/docs/Web/API/URL) objects.

This constructor is safe to use both server and client side, but you have to import it first.

#### Arguments

| Name      | Type   | Required                                       | Description                                     |
| --------- | ------ | ---------------------------------------------- | ----------------------------------------------- |
| ***url*** | string | yes                                            | Absolute or relative URL.                       |
| *`base`*  | string | If `url` is a relative URL, `base` is required | Base URL to use in case `url` is a relative URL |

#### Return value

* A [`URL`](https://developer.mozilla.org/en-US/docs/Web/API/URL)object

#### Example

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

const getApiPathname = ({ state }) => {
  const { pathname } = new URL(state.source.api);
  return pathname;
};
```

### `error` & `warn`

The `frontity` package exports an `error` and `warn` helpers to be used by package developers when they need to either throw an error or log a warn in the console.

#### `error`

This `error` method throws an error. In development, it adds a message that encourage users to visit the Frontity community if they need help.

[**Example of `error` usage**](https://github.com/frontity/frontity/blob/27eb4e0847b002ff26845f5e3f231dc43a637f88/packages/wp-source/src/actions.ts#L203)

```
try {
      new URL(api);
    } catch (e) {
      error("Add the URL of your WordPress REST API in state.source.api.");
    }
```

**Syntax**

```jsx
error(((message: string), (options: ErrorOptions = {})));
```

**Arguments**

| Name            | Type    | Required | Description                                                                                       |
| --------------- | ------- | -------- | ------------------------------------------------------------------------------------------------- |
| ***message***   | string  | yes      | The message that describes the error.                                                             |
| *options*       | object  | no       | Options object.                                                                                   |
| *options.throw* | boolean | no       | Indicate if the function should throw or just log the error in the console using `console.error`. |

#### `warn`

Logs a warning in the console, adding a message that indicates users to visit the Frontity community if they need help. It's intended to be used by Frontity packages.

[**Example of `warn` usage**](https://github.com/frontity/frontity/blob/27eb4e0847b002ff26845f5e3f231dc43a637f88/packages/components/switch.tsx#L29)

```
 ...
 if (hasInvalidComponent) {
    warn("Children of <Switch /> component should be a type of ReactNode");
  }
```

**Syntax**

```jsx
warn((message: string));
```

**Arguments**

| Name          | Type   | Required | Description                              |
| ------------- | ------ | -------- | ---------------------------------------- |
| ***message*** | string | yes      | The message that describes the warning.. |

### `decode`

An entity decoder that decodes HTML numeric entities and [XML named entities](https://html.spec.whatwg.org/multipage/named-characters.html#named-character-references). It works both in the server and the client and it's optimized to be both lightweight and performant.

#### Syntax

```jsx
const decodedText = decode(text);
```

#### Arguments

| Name       | Type   | Required | Description         |
| ---------- | ------ | -------- | ------------------- |
| ***text*** | string | yes      | HTML to be escaped. |

#### Return value

* `string`

#### Example

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

const decodedText = decode("milk &amp; cookies");

console.log(decodedText); // "milk and cookies"
```

### `Slot`

The `<Slot />` component enables the use of a powerful pattern called Slot and Fill. This allows for any React component to be inserted into, or hooked onto, different places within the app, thereby improving extensibility.

This component allows a theme developer to insert named `<Slot>` components in various places in a theme. Other package developers are then able to add *'fill'* components which will be hooked onto the named slots.

#### Rationale

When developing a site the developer is often required to make certain customisations to the structure and/or appearance of the site. This can be difficult to do and necessitates modifying the core code of the theme.

Theme developers are able to facilitate such customisations by adding `<Slot />` components at various places in the theme, e.g. above the header, below the header, before the content, etc...

These 'slots' can then be filled with custom components that have been added by the site developer and which are then 'hooked' onto a particular 'slot' to insert the content in that place on the page.

An example might be as follows - the site developer wants to place a third party ad above the content of each page. The theme developer has thoughtfully provided a slot in that position in the theme:

```jsx
//...
const Content = () => {
  //...
  <Container>
  <Slot name="Before Content">
  //...
  </Container>
  //...
}
```

The site developer is now able to 'hook' a component that returns an ad onto that slot, so that the ad gets rendered in that position on the page. This component is referred to as a *'fill'*.

#### Syntax

```jsx
<Slot name="name of the slot" data={data} myprops={myprops} />
```

or

```jsx
<Slot name="name of the slot" data={data} myprops={myprops}>
  {children}
</Slot>
```

#### Props

All the following props can be passed to the `<Slot/>` component.

| Name             | Type       | Default                               | Required | Description                                                                                                                                                                                                                                                                  |
| ---------------- | ---------- | ------------------------------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `name`           | string     | `undefined`                           | yes      | The name of the Slot. The user of this Slot will have to specify this name in order to insert a Fill component.                                                                                                                                                              |
| `children`       | ReactNode  | `undefined`                           | no       | The component that will be used as a fallback in case that no fill is specified for a particular Slot. You can use any type of data that is a valid React element.                                                                                                           |
| `data`           | ReturnType | `state.source.get(state.router.link)` | no       | Any data that you might want to pass to the Fill. Normally used for passing route data fetched in the parent component. If you don't pass any value, the `<Slot/>` component will set the value of this prop to `state.source.get(state.router.link)` for you automatically. |
| `any other prop` | any        | undefined                             | no       | Any other custom prop. The theme can specify other props and they will be passed down to the Fill.                                                                                                                                                                           |

#### Examples

The simplest example of a Slot would be:

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

const Theme = ({ state }) => (
  <>
    <Slot name="Above Header" />
    <Header />
    <Slot name="Below Header" />
    {/* ... */}
  </>
);
```

Slots can also pass data to the `Fill` components that will be inserted in place of those slots:

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

const Carousel = ({ state }) => {
  // Get latest posts.
  const homeData = state.source.get("/");

  return homeData.items.map((post, index) => {
    const data = state.source.get(post.link);
    return (
      <>
        <Slot data={data} name={`Before post ${index}`} />
        <PostCard />
        <Slot data={data} name={`After post ${index}`} />
      </>
    );
  });
};
```

Slots can also pass arbitrary props to the `Fill` components that will be inserted in place of those slots. In this example we're using 'index' to pass the value of `index` to the Fills:

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

const Carousel = ({ state }) => {
  // Get latest posts.
  const homeData = state.source.get("/");

  return homeData.items.map((post, index) => {
    const data = state.source.get(post.link);
    return (
      <>
        <Slot data={data} index={index} name="Before post" />
        <PostCard />
        <Slot data={data} index={index} name="After post" />
      </>
    );
  });
};
```

The Slot component supports optional children that are rendered if no fills are present. You can use any type of data that is valid as a react element:

```jsx
const Post = () => (
  <>
    {/* ... */}
    <PostTitle />
    <Slot name="Between post title and post meta">
      <Separator />
    </Slot>
    <PostMeta />
    {/* ... */}
  </>
);
```

#### Fills

Fills are added to the `state`, to a common namespace called `fills`. Each fill consists of a configuration object that should be given a unique key and assigned to a namespace. To learn more about namespaces see [this section](https://docs.frontity.org/learning-frontity/namespaces) of the docs.

More than one Fill can be hooked onto any single Slot, and these can be ordered according to a `priority` attribute assigned to the Fill.

```jsx
// my-frontity-app/packages/my-theme/src/index.js

const state = {
  fills: {
    namespace: {
      nameOfTheFill: {
        slot: "Name of the slot they want to fill", // This has to match the `name` prop passed to <Slot/>
        library: "libNamespace.ComponentName",
        priority: 5,
        props: {
          // Object with props that will be passed to the component.
        },
      },
    },
  },
};
```

Fills configuration objects structure:

| Name         | Description                                                                                  | Required |
| ------------ | -------------------------------------------------------------------------------------------- | -------- |
| `object key` | Name of your fill, must be unique.                                                           | yes      |
| `slot`       | Name of the slot they want to fill.                                                          | yes      |
| `library`    | Name of the component they want to use. This is obtained from `libraries.fills` (see below). | yes      |
| `priority`   | Priority of the fill. Default is 10. (lower value means higher priority)                     | no       |
| `props`      | Object with props that will be passed to the component.                                      | no       |

Fills configuration objects can have a false value. This is useful if a package creates a fill by default and a user (or another package) wants to turn it off.

```jsx
// my-frontity-app/packages/my-theme/src/index.js

const state = {
  fills: {
    namespace: {
      nameOfTheFill: false,
    },
  },
};
```

The actual components that will be hooked onto a `<Slot>` should be exposed in `libraries.fills` by Frontity packages. They can be defined anywhere you like, as long as you can import them and pass to `libraries.fills`. For example:

```jsx
// my-frontity-app/packages/my-theme/src/fills.js

export const FillComponent = ({
  // If the Slot creator has passed a `data` prop to the Slot,
  // you can access it here. Otherwise, this prop will be automatically
  // populated with the value of `state.source.get(state.router.link)`
  data,

  // Any other props passed by the creator of the Slot will be available as well!
  ...props
  }) => (
    <div>
      This is the fill content
    </div>
  )
}
```

```jsx
// my-frontity-app/packages/my-theme/src/index.js

import { MyFillComponent } from "./fills"; // This is the component defined below

export default {
  state: {
    //...
  },
  actions: {
    //...
  },
  libraries: {
    fills: {
      libNamespace: {
        ComponentName: MyFillComponent,
      },
    },
  },
};
```

Note that `libNamespace.ComponentName` here matches the value of `state.fills.namespace.nameOfTheFill.library` above. `FillComponent` here is the actual component which is defined elsewhere and may be imported. The return value of this component, i.e. `FillComponent`, is the content that will be inserted into HTML at the position of the `<Slot>` that it is attached to.


# Features packages

Features packages are those packages that add a specific feature to a Frontity project. They need to be defined and configured in the `frontity.settings.js` file so Frontity can properly use them in the project.

Most of the logic needed for specific features in a Frontity project are delegated in packages. Some of the packages contain essential features like [*routing*](/frontity-packages/features-packages#router-package) and [*source*](/frontity-packages/features-packages#source-package), so they will be used by most of the projects. Other optional features (like [*analytics*](/frontity-packages/features-packages#analytics-packages)) can be easily implemented through other packages.

## Official packages

### Source package

This package is in charge of getting data from WordPress and make it accesible from React components.

* [`@frontity/wp-source`](/frontity-packages/features-packages/wp-source)

### Router package

This package is in charge of managing (React) routes in a Frontity project.

* [`@frontity/tiny-router`](/frontity-packages/features-packages/tiny-router)

### Render package

This package is in charge of converting HTML to React.

* [`@frontity/html2react`](/frontity-packages/features-packages/html2react)

### SEO packages

These packages are designed to get automatically all the data from WordPress SEO plugins and render it (along with the content) in the final HTML.

* [`@frontity/head-tags`](/frontity-packages/features-packages/head-tags)
* [`@frontity/yoast`](/frontity-packages/features-packages/yoast)

### Ad packages

These packages allow you to insert ads in your Frontity projects from services such as Google Ad Manager.

* [`@frontity/google-ad-manager`](/frontity-packages/features-packages/google-ad-manager)
* [`@frontity/smart-adserver`](/frontity-packages/features-packages/smart-ads)

### Analytics packages

A set of official Analytics Frontity packages that you can use to easily add analytics services to your project.

* [`@frontity/google-analytics`](/frontity-packages/features-packages/analytics/google-analytics)
* [`@frontity/google-tag-manager-analytics`](/frontity-packages/features-packages/analytics/google-tag-manager-analytics)
* [`@frontity/comscore-analytics`](/frontity-packages/features-packages/analytics/comscore-analytics)

### Comments packages

This package adds support for WordPress' native comments.

* [`@frontity/wp-comments`](/frontity-packages/features-packages/wp-comments)

## Community packages

These are other packages for Frontity built by the community that you can use to add new functionality to your site (listed in alphabetical order):

### Contact Form 7

A package developed by Aamodt Group to use the Contact Form 7 plugin with Frontity. It adds improvements and bug fixes to the [previous CF7 package](https://www.npmjs.com/package/frontity-contact-form-7) built by Imran Sayed and Smit Patadiya.

* [`@aamodtgroup/frontity-contact-form-7`](https://www.npmjs.com/package/@aamodtgroup/frontity-contact-form-7)

### ElasticPress

This package created by 10up enhances your Frontity theme by supercharging the search experience with ElasticPress.

* [`@10up/frontity-elasticpress`](https://www.npmjs.com/package/@10up/frontity-elasticpress)

### Gravity Forms

A package developed by Aamodt Group that adds support for the Gravity Forms plugin.

* [`@aamodtgroup/frontity-gravity-forms`](https://www.npmjs.com/package/@aamodtgroup/frontity-gravity-forms)

### Microsoft Clarity

An analytics package created by mtadros to use Microsoft Clarity with Frontity.

* [`frontity-microsoft-clarity`](https://www.npmjs.com/package/frontity-microsoft-clarity)

### WP Job Openings

This package built by Aswm Innovations adds support for WP Job Openings plugin.

* [`@awsmin/frontity-wp-job-openings`](https://www.npmjs.com/package/@awsmin/frontity-wp-job-openings)

{% hint style="info" %}
You can find more community packages by searching for the [`frontity`](https://www.npmjs.com/search?q=keywords:frontity) tag at npmjs.com.
{% endhint %}


# @frontity/wp-source

API reference of \`@frontity/wp-source\` package

This package is in charge of getting the data from self-hosted WordPress or WordPress.com sites, and make it available from our React components.

## Table of Contents

* [Installation](/frontity-packages/features-packages/wp-source#installation)
* [Settings](/frontity-packages/features-packages/wp-source#settings)
  * [REST API](/frontity-packages/features-packages/wp-source#rest-api-settings)
    * [`state.source.url`](/frontity-packages/features-packages/wp-source#state-source-url)
    * [`state.source.api`](/frontity-packages/features-packages/wp-source#state-source-api)
    * [`state.wpSource.isWpCom`](/frontity-packages/features-packages/wp-source#state-wpsource-iswpcom)
    * [`state.wpSource.prefix`](/frontity-packages/features-packages/wp-source#state-wpsource-prefix)
  * [Custom paths](/frontity-packages/features-packages/wp-source#custom-paths)
    * [`state.source.subdirectory`](/frontity-packages/features-packages/wp-source#state-source-subdirectory)
    * [`state.source.homepage`](/frontity-packages/features-packages/wp-source#state-source-homepage)
    * [`state.source.postsPage`](/frontity-packages/features-packages/wp-source#state-source-postspage)
    * [`state.source.categoryBase`](/frontity-packages/features-packages/wp-source#state-source-categorybase)
    * [`state.source.tagBase`](/frontity-packages/features-packages/wp-source#state-source-tagbase)
    * [`state.source.postEndpoint`](/frontity-packages/features-packages/wp-source#state-source-postendpoint)
  * [Custom requests](/frontity-packages/features-packages/wp-source#custom-requests)
    * [`state.source.params`](/frontity-packages/features-packages/wp-source#state-source-params)
    * [`state.source.auth`](/frontity-packages/features-packages/wp-source#state-source-auth)
    * [`state.source.redirections`](/frontity-packages/features-packages/wp-source#state-source-redirections)
  * [Custom Post Types](/frontity-packages/features-packages/wp-source#custom-post-types)
    * [`state.source.postTypes`](/frontity-packages/features-packages/wp-source#state-source-posttypes)
    * [`state.source.taxonomies`](/frontity-packages/features-packages/wp-source#state-source-taxonomies)
* [How to use](/frontity-packages/features-packages/wp-source#how-to-use)
* [API Reference](/frontity-packages/features-packages/wp-source#api-reference)
  * [Actions](/frontity-packages/features-packages/wp-source#actions)
    * [`actions.source.fetch()`](/frontity-packages/features-packages/wp-source#actions-source-fetch)
  * [State](/frontity-packages/features-packages/wp-source#state)
    * [`state.source.get()`](/frontity-packages/features-packages/wp-source#state-source-get)
    * [`state.source[taxonomy][id]`](/frontity-packages/features-packages/wp-source#state-source-taxonomy-id)
    * [`state.source[type][id]`](/frontity-packages/features-packages/wp-source#state-source-type-id)
    * [`state.source.author[id]`](/frontity-packages/features-packages/wp-source#state-source-author-id)
  * [Libraries](/frontity-packages/features-packages/wp-source#libraries)
    * [`libraries.source.api.get()`](/frontity-packages/features-packages/wp-source#libraries-source-api-get)
    * [`libraries.source.populate()`](/frontity-packages/features-packages/wp-source#libraries-source-populate)
    * [`libraries.source.handlers`](/frontity-packages/features-packages/wp-source#libraries-source-handlers)
    * [`libraries.source.redirections`](/frontity-packages/features-packages/wp-source#libraries-source-redirections)
    * [`libraries.source.parse()`](/frontity-packages/features-packages/wp-source#libraries-source-parse)
    * [`libraries.source.stringify()`](/frontity-packages/features-packages/wp-source#libraries-source-stringify)
    * [`libraries.source.normalize()`](/frontity-packages/features-packages/wp-source#libraries-source-normalize)

## Installation

Add the `wp-source` package to your project:

```
npm i @frontity/wp-source
```

{% hint style="info" %}
Both of the starter themes (`@frontity/mars-theme` & `@frontity/twentytwenty-theme`) available when doing `npx frontity create` already include this `wp-source` package.
{% endhint %}

## Settings

This package needs to be included in your `frontity.settings.js` file as one of the packages that will be part of the Frontity project:

```javascript
module.exports = {
  packages: [
    "@frontity/mars-theme",
    "@frontity/tiny-router",
    {
      name: "@frontity/wp-source",
      state: {
        source: {
          url: "https://wpsite.com/",
        },
      },
    },
  ],
};
```

These are the settings you can configure for this package in your `frontity.settings.js` file:

### REST API settings

{% hint style="info" %}
We recommend you to check the guide [**Setting the URL of the WordPress data source**](https://docs.frontity.org/guides/setting-url-wordpress-source-data) to get a more practical explanation of how to properly set the URL of the WordPress data source by using the properties of this package and taking into account the different WordPress scenarios.
{% endhint %}

#### `state.source.url` ![](https://img.shields.io/badge/REQUIRED-red.svg)

The URL of your WordPress backend installation. The default value of this property is derived from `state.frontity.url`.

Example:

```javascript
// frontity.settings.js
export default {
  packages: [
    {
      name: "@frontity/wp-source",
      state: {
        source: {
          url: "https://test.frontity.org",
        },
      },
    },
  ],
};
```

{% hint style="info" %}
If you are using [Embedded Mode](https://docs.frontity.org/architecture/embedded-mode) for your Frontity project, and the `state.frontity.url` property is set, you do not have to also set the `state.source.url` property as this will be the same as the value in the `state.frontity.url` property.
{% endhint %}

#### `state.source.api`

The URL of your WordPress REST API endpoint.

{% 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 properties like `state.source.url` or `state.wpSource.isWpCom`).

Check the guide [Setting the URL of the WordPress data source](https://docs.frontity.org/guides/setting-url-wordpress-source-data) to understand the computed values of `state.source.api` for every WordPress scenario.
{% endhint %}

#### `state.wpSource.isWpCom`

Boolean value to indicate if the WordPress installation used as the source of data is a Personal or Premium WordPress.com plan.

This value will be `false` by default and will be automatically computed to `true` if needed in most of the cases.

This property only needs to be set manually to `true` if you're using a Personal or Premium WordPress.com plan.

{% hint style="info" %}
Check the guide [Setting the URL of the WordPress data source](https://docs.frontity.org/guides/setting-url-wordpress-source-data) to understand the value of this property depending on the WordPress scenario.
{% endhint %}

Example:

```javascript
// frontity.settings.js
export default {
  packages: [
    {
      name: "@frontity/wp-source",
      state: {
        source: {
          url: "https://test-premium-plan.frontity.org",
        },
        wpSource: {
          isWpCom: true,
        },
      },
    },
  ],
};
```

#### `state.wpSource.prefix`

By using this property you can specify the prefix of your REST API, for example `"/wp-json"` or `"?rest_route=/"`. The default value is `"/wp-json"`.

This option should only be set if you have changed the path to the REST API endpoint in your WordPress installation. If you have not done that or you're not sure what it means, you can safely ignore this option.

### Custom paths

#### `state.source.subdirectory`

A name or path indicating the subdirectory of your domain where your Frontity site lives. For example, if your site is in <https://mysite.com/blog>, you have to use it with the value of `blog` or `/blog`. It also transform links of the entities that come from the REST API.

#### `state.source.homepage`

This option allows you to show a specific page when accessing the homepage of your site. For example, if you set this value to `/about-us` then that page will be shown if you access `/`.

You have to configure your WordPress with the same setting.

![](https://frontity.org/wp-content/uploads/2021/04/homepage-displays-static-page.png)

{% hint style="warning" %}
As this option overrides the `/` route, you should set `state.source.postsPage` as well in order to be able to access the posts archive in a different route.

Have a look at [this video](https://www.loom.com/share/277c9bfb9b664764bcc900aad31f80ea) to learn more about this
{% endhint %}

#### `state.source.postsPage`

This option allows you to show the posts archive when accessing a specific URL of your site, instead of the homepage. For example, if you set this value to `/blog`, then the posts archive will be shown if you access `/blog` instead of `/`. It is useful when used in combination with `state.source.homepage`.

You have to configure your WordPress with the same setting.

![](https://frontity.org/wp-content/uploads/2021/04/homepage-displays-static-page.png)

#### `state.source.categoryBase`

Change the base prefix of URLs for category pages with the indicated one.

{% hint style="warning" %}
For this option to work well, you have to put the same value in the WordPress site options.
{% endhint %}

#### `state.source.tagBase`

Change the base prefix of URLs for tag pages with the indicated one.

{% hint style="warning" %}
For this option to work well, you have to put the same value in the WordPress site options.
{% endhint %}

#### `state.source.postEndpoint`

Set the endpoint against which calls to the REST API are made **when posts are requested**, i.e. when fetching a single post, the post archive, date archives, categories, tags, authors, etc. This is useful when you want to use another post type as your default, for example “products”.

The default value is `"posts"`.

### Custom requests

#### `state.source.params`

Object of params that will be used in every call to the WP REST API when using `actions.source.fetch`. This is useful to filter fields from the REST API, change the default `per_page` value and so on. For example, if you set this value to

```javascript
module.exports = {
  packages: [
    {
      name: "@frontity/wp-source",
      state: {
        source: {
          api: "https://site.com/wp-json",
          params: {
            per_page: 5,
            type: ["post", "page"],
          },
        },
      },
    },
  ],
};
```

and then you visit a URL (or use `actions.source.fetch`), the query part of the HTTP call to the REST API will be `per_page=5&type[]=post&type[]=page`.

#### `state.source.auth`

This option is a property which can hold authentication information. This could be a JWT token or a Basic Authentication string, or another type of authentication.

Values can be passed to `state.source.auth` in a variety ways, e.g. via `frontity.settings.js` or by setting it in the way that any other piece of frontity state is.

```javascript
// frontity.settings.js
const state = {
  source: {
    auth: "Basic YWFhOmJiYg",
  },
};
```

Additionally the value of `state.source.auth` can be set via a **query string**. If a `frontity_source_auth` [Frontity Query Option](https://docs.frontity.org/guides/frontity-query-options) param is present in the URL `state.source.auth` will use its value. Values passed in this way will be removed from the `initialLink` URL and added to `state.frontity.options`.

> Note that the Frontity Query Option parameters are camelCased when they are added to `state.frontity.options`, so the `frontity_source_auth` query string param will become `state.frontity.options.sourceAuth` once added.

The value of `state.source.auth` can also be set from an **environmental variable**. If frontity detects a `FRONTITY_SOURCE_AUTH` environmental variable, it will pass its value to `state.source.auth`.

> Note that the value passed from the URL query string takes precedence over the value from the env variable.
>
> Frontity loads environmental variables from .env files using the <https://github.com/motdotla/dotenv/> package.

This value can be used in the `auth` property of [`libraries.source.api.get`](/frontity-packages/features-packages/wp-source#libraries-source-api-get).

Crucially, `state.source.auth` is **removed in the `afterSSR()` action**, so if `state.source.auth` is present in the state on the server its value will not be sent to the client, thus confidential credentials are not revealed client-side.

#### `state.source.redirections`

Via this `wp-source` package, Frontity has support for 3xx Redirections that are stored in the WordPress database. Such redirections can be added for example via the popular [Redirection plugin](https://wordpress.org/plugins/redirection/).

Through the property `state.source.redirections` we can configure how we want to handle the redirections. This property can have one of the following values:

* `"no"` - Does not handle the redirections at all. This is the **default**.
* [`"404"`](https://docs.frontity.org/guides/redirections-with-frontity#404) - Only send the additional request to the WordPress instance if the original request has returned a 404 error.
* [`"all"`](https://docs.frontity.org/guides/redirections-with-frontity#all) - Always make an additional request to the WordPress instance to check if there exists a redirection. This means that for every single `actions.source.fetch()` there will be a parallel request to the WordPress server that is fired "just in case" the `actions.source.fetch()` returns a 404. If the `actions.source.fetch()` is successful, the result of fetching the redirection is discarded. If `actions.source.fetch()` fails, Fronity waits for the response from fetching the redirection and if that is successful, uses its result.
* `string` - 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. Note that the shorthand character classes will have to be escaped, so for example instead of `\d`, you will need to write `\\d`.
* `string[]` - 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 error.

Some example valid values are:

* `"no"`
* `"all"`
* `"404"`
* `"RegExp:/some-post/(\\d*)"`
* `"RegExp:/post-(\\w*)/(\\d*)"`
* `["404", "RegExp:/some-post/", "RegExp:/another-post"]`

{% hint style="info" %}
Have a look at the guide [**Redirections with Frontity**](https://docs.frontity.org/guides/redirections-with-frontity) to learn more about this.
{% endhint %}

### Custom Post Types

#### `state.source.postTypes`

This option allows you to show the Custom Post Types you create at WordPress when accessing their URLs. It is an array of objects, each object being a different CPT. It has three arguments:

| Name           | Type   | Required | Description                                                                    |
| -------------- | ------ | -------- | ------------------------------------------------------------------------------ |
| **`type`**     | string | yes      | The slug you configured for your Custom Post Type                              |
| **`endpoint`** | string | yes      | REST API endpoint from where this post type can be fetched.                    |
| `archive`      | string | no       | the URL of the archive of this Custom Post Type, where all of them are listed. |

Differentiating `type` and `endpoint` may be confusing as they are usually the same. You can confirm you are doing it correctly going to the CPT `endpoint` :

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

So in this case, the settings would be:

```javascript
postTypes: [
  {
    type: "movies",
    endpoint: "movies",
    archive: "/movies_archive",
  },
];
```

#### `state.source.taxonomies`

Similar to `postTypes`setting, this one allows you to show the lists of posts of a Custom Taxonomies you create at WordPress when accessing their URLs. It is an array of objects, each object being a different Custom Taxonomy. It has four arguments:

| Name               | Type   | Required | Description                                                                                                                                                                                                                                                                                                 |
| ------------------ | ------ | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`taxonomy`**     | string | yes      | Taxonomy slug. The slug you configured for your Custom Taxonomy. If your taxonomy is registered with a rewrite, use that instead.                                                                                                                                                                           |
| **`endpoint`**     | string | yes      | REST API endpoint from where this post type can be fetched.                                                                                                                                                                                                                                                 |
| `postTypeEndpoint` | string | no       | REST API endpoint from which posts of this taxonomy can be fetched. If the Custom Taxonomy is meant to load Custom Post Types instead, you have to add its endpoint here. To clarify, although optional for posts in the case of a Custom Post Type this argument is **required**. Default value is `posts` |
| `params`           | object | no       | Extra params to be used while fetching the list of posts.                                                                                                                                                                                                                                                   |

Differentiating `taxonomy` and `endpoint`may be confusing as they usually are the same too. You can confirm you are doing it correctly by going to the Custom Taxonomy `endpoint` :

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

Note that in this case `taxonomy`and `endpoint`are different. In the next example, we will fetch CPT "movies" instead of "posts", and add some params. It would be something like this:

```javascript
taxonomies: [
  {
    taxonomy: "actors",
    endpoint: "actor",
    postTypeEndpoint: "movies",
    params: {
      per_page: 5,
      _embed: true,
    },
  },
];
```

## How to use

This package will automatically retrieve data from the related WordPress routes when accesing a React route.

{% hint style="info" %}
The `@frontity/wp-source` package requires pretty permalinks to be enabled on the WordPress admin. For more info check the guide [WordPress requirements for Frontity](https://docs.frontity.org/guides/what-are-the-requisites-of-wordpress-for-frontity#have-pretty-permalinks-activated).
{% endhint %}

The data got from WordPress REST API is organized and normalized in the state. This "normalization" of the data means the data is organized in the state in a way so there's no duplicated data in it and there's only one source of truth.

The state works with two main concepts: **links** and **entities**.

The state is designed so that you can know which entities correspond to which link, and then access the data of these entities in a simple way.

Because of this there's a 2 step process to get the information from a link:

1. Get the data related to the link
2. Get the data related to the entities available in that link

{% hint style="warning" %}
For the data to exist, it will be necessary to request them previously using the `fetch` action.
{% endhint %}

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

// In a React component that uses "connect":
const CategoryNature = ({ state, actions }) => {
  // 1. fetch data related to a path
  // With this useEffect we make the call to fetch
  // only the first time the component is rendered.
  // When the data is fetched, the state is updated with the new data
  // so the component is re-rendered and "data" will get proper content

  useEffect(() => {
    actions.source.fetch("/category/nature/");
  }, []);

  // 2. get data from frontity state
  const data = state.source.get("/category/nature/");

  // 3. get entities from frontity state
  if (data.isCategory) {
    // the category entity
    const category = state.source.category[data.id];

    // posts from that category
    const posts = data.items.map(({ type, id }) => state.source[type][id]);

    // 4. render!
    return (
      <>
        <h1>{category.name}</h1>
        {posts.map((p) => (
          <a href={p.link}>{p.title.rendered}</a>
        ))}
      </>
    );
  }

  return null;
};

export default connect(CategoryNature);
```

{% hint style="info" %}
If you want to know more about how to use the `wp-source` package, here you have some videos where the Frontity DevRel team talks about it:

* 📺 [Frontity Talks 2020-01 - wp-source & CSS In JS \[1:36\]](https://www.youtube.com/watch?v=e-_66W8pfdY\&t=96s)
* 📺 [Frontity Talks 2020-02 - Pagination example & wp-source (state & fetch) \[17:53\]](https://www.youtube.com/watch?v=eW5xZlpcqQk\&t=1073s)
  {% endhint %}

## API Reference

The [`wp-source` package](https://github.com/frontity/frontity/tree/dev/packages/wp-source) implements the [interface defined in the `source` package](https://github.com/frontity/frontity/blob/dev/packages/source/types.ts) and [adds some extra API](https://github.com/frontity/frontity/blob/dev/packages/wp-source/types.ts).

### Actions

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).

{% hint style="info" %}
Read more about actions [here](https://docs.frontity.org/learning-frontity/actions).
{% endhint %}

#### `actions.source.fetch()`

This action fetches all entities related to a `link`, i.e. the pathname of a URL in your site.

It populates the state with both:

* An entry in `state.source.data` with information about that link.
* Normalized entities in relevant part of the state, like `state.source.post`, `state.source.category` or `state.source.author` and so on.

**Syntax**

```typescript
(link: string, options: object) => Promise`
```

**Arguments**

| Name                | Type    | Required | Description                                                 |
| ------------------- | ------- | -------- | ----------------------------------------------------------- |
| ***`link`***        | string  | yes      | Link representing a REST API endpoint or custom handler     |
| *`options`*         | object  | no       | REST API endpoint from where this post type can be fetched. |
| *`options`*.`force` | boolean | -        | The entities should be fetched again.                       |

**Return value**

| Type      | Description                                                                                              |
| --------- | -------------------------------------------------------------------------------------------------------- |
| `Promise` | it doesn't return data but a promise that is resolved when the action is finished (and state is updated) |

All received data are populated in `state.source` and are accessible using the methods explained in the next section.

```javascript
actions.source.fetch("/category/nature/");
```

Even though actions don't return data, they return a promise that resolves when the action is finished.

So, you can do something like this:

```javascript
await actions.source.fetch("/some-post");
```

which is useful when you need to access the new state just after calling the action:

```javascript
await actions.source.fetch("/some-post"); // <- Wait until we fetch "/some-post".
const somePost = state.source.get("/some-post"); // <- The data will exist.
```

In React components, you won't need to use `async/await` with `fetch` because:

* [`useEffect` doesn't directly accept `async` functions](https://reactjs.org/docs/hooks-reference.html#useeffect) although [it can contain `async`](https://www.robinwieruch.de/react-hooks-fetch-data) functions
* They re-render when the `state` accessed changes.

```javascript
const SomePost = ({ actions, state }) => {
  useEffect(() => {
    // No need to use `async/await` here
    actions.source.fetch("/some-post");
  }, []);

  // The data will not exist at first, `dataPost.isReady` will be false.
  // But then, it will rerender when `actions.source.fetch` is finished.
  const dataPost = state.source.get("/some-post");

  // This will work just fine.
  return dataPost.isReady ? <Post link="/some-post" /> : <Loading />;
};
```

When `fetch` is called *again* for the same `link` it does nothing, as all the entities have already been fetched and there is no need to request them again. If you do want to fetch them again, you can pass an options object to `source.fetch` with `force: true`:

```javascript
actions.source.fetch("/category/nature/", { force: true });
```

{% hint style="info" %}
The use of `actions.source.fetch()` is recommended over other isomorphic methods to fetch data such as `axios` or `superagent`, because:

1. It does not increase the bundle size
2. It prevents Frontity projects from having duplicated libraries doing the same job

The use of `actions.source.fetch()` is also recommended over `window.fetch` because although `window.fetch` exists in the browser it is not isomorphic and doesn't exist in Node.
{% endhint %}

**Relationship with state.router.autoFetch**

Every time you go to a new link from the Client Side (by using `actions.router.set` for example) a new fetch should be done for that new link so the data of that link is properly populated to the state.

Thanks to the settings property `state.router.autoFetch` with a default value of true, every time you browse to a new page (Client Side Navigation) the fetch of the data in that page will we done automatically for you.

Have a look at this video to learn more about this:

{% embed url="<https://youtu.be/odmg2Br1Zrw?t=25>" %}

### State

#### `state.source.get()`

Returns an object that gives you info about the type of that link and related entities.

**Syntax**

```typescript
(link: string) => object`
```

**Arguments**

| Name         | Type   | Required | Description                                             |
| ------------ | ------ | -------- | ------------------------------------------------------- |
| ***`link`*** | string | yes      | Link representing a REST API endpoint or custom handler |

**Return value**

| Type   | Description                                        |
| ------ | -------------------------------------------------- |
| object | Info about the type of data represented in the URL |

For exampe:

```javascript
state.source.get("/category/nature/");
```

will return something like:

```javascript
{
  // Entity properties.
  taxonomy: "category",
  id: 7,
  link: "/category/nature/page/3?s=park",
  query: {
    s: "park"
  },

  // Booleans that identify the type of link.
  isArchive: true,
  isCategory: true,
  isTaxonomy: true,

  // Booleans that show the fetch status.
  isFetching: false,
  isReady: true,

  // Archive properties.
  items: [{ type: "post", id: 60, link: "..." }, ...],
  total: 53,
  totalPages: 6,
  page: 3,
  route: "/category/nature",
  next: "/category/nature/page/4?s=park",
  previous: "/category/nature/page/2?s=park",

  // Search properties.
  isSearch: true,
  searchQuery: "park",
}
```

The information to distinguish each type of link is based on the [WP Template Hierarchy](https://wphierarchy.com/) and is as follows:

* archives: `isArchive`
  * taxonomy: `isTaxonomy`
    * category: `isCategory`
    * tag: `isTag`
    * deal: `isDeal`
  * author: `isAuthor`
  * postTypeArchive: `isPostTypeArchive`
    * post: `isHome`, `isPostArchive` (`isFrontPage` optional)
    * product: `isProductArchive`
  * date: `isDate`
* postTypes: `isPostType`
  * post: `isPost`
  * page: `isPage` (`isFrontPage` optional)
  * product: `isProduct`
  * media: `isMedia`, `isAttachment`
* 404: `is404`

Additionally, if calling `get()` has returned a status code higher than `400`, we add information about the error to the state. For example, if an error code was `500`, the state will include the following properties:

```javascript
{
  isError: true,
  is500: true,
  errorStatus: 500,
  errorStatusText: "Some string describing the error",

  // booleans that describe the fetch status
  isReady: true,
  isFetching: false
}
```

Properties added to each type are also based on the [WP REST API](https://developer.wordpress.org/rest-api/reference/):

* taxonomy: `taxonomy`, `id`
* author: `id`
* postTypeArchive: `type`
* date: `year`, `month`, `date`
* postType: `type`, `id`

#### `state.source[taxonomy][id]`

Access category, tag, or custom taxonomy’s entities. These entities have the same schema as specified in the [WP REST API](https://developer.wordpress.org/rest-api/reference/).

{% hint style="warning" %}
We are actually changing the WP REST API response, but **only for tags**, in which we are replacing the `taxonomy` value from `post_tag` to `tag`.
{% endhint %}

```
source.category[2]
source.tag[13]
source.deal[3]
```

#### `state.source[type][id]`

Access posts, pages, attachments or custom post type’s entities. These entities have the same schema as specified in the [WP REST API](https://developer.wordpress.org/rest-api/reference/).

```
source.post[60]
source.page[7]
source.product[36]
```

#### `state.source.author[id]`

Access author entities. These entities have the same schema as specified in the [WP REST API](https://developer.wordpress.org/rest-api/reference/).

```
source.author[4]
```

### Libraries

#### `libraries.source.api.get()`

Request entity from the WordPress REST API.

**Syntax**

```typescript
(options: object) => Promise;
```

**Arguments**

| Name                       | Type    | Required | Description                                                                                                                                                                                                                                |
| -------------------------- | ------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| *`options`*                | object  | yes      | options object                                                                                                                                                                                                                             |
| *`options`*.**`endpoint`** | string  | yes      | Name of the endpoint if is a `/wp/v2` endpoint (e.g. `posts`), or the full path of other REST endpoints (e.g. `/acf/v3/posts`).                                                                                                            |
| *`options`*.`params`       | object  | no       | Any parameter that will be included in the query params.                                                                                                                                                                                   |
| *`options`*.`auth`         | string  | no       | Allows the Authorization header on the fetch() request to be set. If not specified, will use the value from [`state.source.auth`](/frontity-packages/features-packages/wp-source#state-source-auth) if that value is present in the state. |
| *`options`*.`api`          | string  | no       | Overrides the value set with `api.set.`                                                                                                                                                                                                    |
| *`options`*.`isWpCom`      | boolean | no       | Overrides the value set with `api.set.`                                                                                                                                                                                                    |

**Return value**

| Type      | Description                                                                                              |
| --------- | -------------------------------------------------------------------------------------------------------- |
| `Promise` | it doesn't return data but a promise that is resolved when the action is finished (and state is updated) |

For more info, visit the [WP REST API reference](https://developer.wordpress.org/rest-api/reference).

**Example**

```javascript
const { api } = libraries.source;

// Get posts from categories 2, 3 and 4
const postsCategories = await api.get({
  endpoint: "posts",
  params: { _embed: true, categories: "2,3,4" },
});

// Get the page 14
const page14 = await api.get({
  endpoint: "pages",
  params: { _embed: true, include: "14" },
});

// Other endpoints:
const postBeautiesGullfoss = await api.get({
  endpoint: "/acf/v3/posts",
  params: { slug: "/the-beauties-of-gullfoss" },
});
```

#### `libraries.source.populate()`

Add entities to the Frontity state.

```typescript
(options: object) => Promise;
```

**Arguments**

| Name                       | Type    | Required | Description                                                                                                                                                                                                        |
| -------------------------- | ------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| *`options`*                | object  | yes      | Options object                                                                                                                                                                                                     |
| *`options`*.**`response`** | object  | yes      | The response object returned by `api.get().`                                                                                                                                                                       |
| *`options`*.**`state`**    | object  | yes      | The state object from the Frontity store.                                                                                                                                                                          |
| *`options`*.`subdirectory` | string  | no       | Domain's subdirectory where your Frontity site is accessible. When this options is passed, this subdirectory is added to the entities' links. \</br> Default Value is value defined in `state.source.subdirectory` |
| *`options`*.`force`        | boolean | no       | Value indicating if the entities should be overwritten \</br> Default Value is `false`                                                                                                                             |

**Return value**

| Type    | Description                                                                                  |
| ------- | -------------------------------------------------------------------------------------------- |
| `Array` | An array of objects with attributes `type`, `id` and `link` representing the added entities. |

Entities are normally never overwritten. So, if an entity already exists in the state and a new one is fetched, the one in the state will prevail. If you want to overwrite them, `populate` should be called with `force: true`.

**Example**

```javascript
const response = await libraries.source.api.get({ endpoint: "posts" });
const entitiesAdded = await libraries.source.populate({ response, state });

entitiesAdded.forEach(({ type, id, link }) => {
  console.log({ type, id, link });
});
```

#### `libraries.source.handlers`

Handlers are objects that associate a path pattern with a function that gets the entities contained in that path. These `handlers` are used when `actions.source.fetch` is called.

A handler is defined by an object with the following properties:

| Name           | Type     | Required | Description                                                                                                                                                                                                                                                                                                                               |
| -------------- | -------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`name`**     | string   | yes      | Identifier of the handler.                                                                                                                                                                                                                                                                                                                |
| **`priority`** | number   | yes      | Number that lets `fetch` to know in which order handlers should be evaluated.                                                                                                                                                                                                                                                             |
| **`pattern`**  | regExp   | yes      | Pattern which paths are compared with. We use [path-to-regexp](https://github.com/pillarjs/path-to-regexp) under the hood, so check its documentation to know how to write patterns. If the pattern you are trying to match doesn't include a path, but only RegExp, you need to use the following syntax: `pattern: "RegExp:foo(?!bar)"` |
| **`func`**     | function | yes      | Asynchronous function that retrieves entities and adds all info to the state.                                                                                                                                                                                                                                                             |

**The func property**

**Arguments**

The `func` property defined will receive an object with the following properties

| Name        | Type    | Description                                                                                                          |
| ----------- | ------- | -------------------------------------------------------------------------------------------------------------------- |
| `link`      | string  | The link that are being fetched.                                                                                     |
| `params`    | string  | values obtained from the pattern after a match                                                                       |
| `state`     | object  | Frontity state.                                                                                                      |
| `libraries` | object  | Frotity libraries.                                                                                                   |
| `force`     | boolean | f the etities should be fetched again. Internally, this parameter will be passed to the `actions.source.fetch` call. |

**Return**

| Type      | Description                      |
| --------- | -------------------------------- |
| `Promise` | Promise resolving to custom data |

`libraries.source.handlers` is an array., so **to add new handlers we can use `libraries.source.handlers.push()`**

**Example**

```javascript
// A handler example to retrieve products
libraries.source.handlers.push({
  name: "product",
  priority: 10,
  pattern: "/product/:slug",
  func: async ({ link, params, state, libraries, force }) => {
    // 1. get product
    const response = await libraries.source.api.get({
      endpoint: "products",
      params: { slug: params.slug },
    });

    // 2. add product to state
    const [product] = await libraries.source.populate({
      response,
      state,
      force,
    });

    // 3. add link to data
    Object.assign(state.source.data[link], {
      id: product.id,
      type: product.type,
      isPostType: true,
      isProduct: true,
    });
  },
});
```

#### `libraries.source.redirections`

Redirections are objects that associate a path pattern with a function that returns a new path. These `redirections` are used when `actions.source.fetch` is executed, before `handlers`.

A redirection is defined by an object with the following properties:

| Name           | Type     | Required | Description                                                                                                                                                                          |
| -------------- | -------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **`name`**     | string   | yes      | Identifier of the redirection.                                                                                                                                                       |
| **`priority`** | number   | yes      | Let `fetch` to know in which order redirections should be evaluated.                                                                                                                 |
| **`pattern`**  | regExp   | yes      | Pattern which paths are compared with. We use [path-to-regexp](https://github.com/pillarjs/path-to-regexp) under the hood, so check its documentation to know how to write patterns. |
| **`func`**     | function | yes      | Function that returns a new path. It receives an object with the params obtained after a match.                                                                                      |

**The func property**

**Arguments**

The `func` property defined will receive an object with the following properties

| Name   | Type   | Description                     |
| ------ | ------ | ------------------------------- |
| `slug` | string | The link that is being fetched. |

**Return**

| Type   | Description |
| ------ | ----------- |
| string | a new path  |

**Example**

```javascript
// A redirection example to change tag base prefix
libraries.source.redirections.push({
  name: "tags",
  priority: 10,
  pattern: "/tag/:slug/",
  func: ({ slug }) => `/label/${slug}/`,
});
```

#### `libraries.source.parse()`

Utility for parsing links.

**Syntax**

```typescript
(link: string) => object;
```

**Arguments**

| Name     | Type   | Required | Description                                                               |
| -------- | ------ | -------- | ------------------------------------------------------------------------- |
| *`link`* | string | yes      | any link that points to entities in your site (links, custom lists, etc.) |

**Return value**

| Name                    | Type   | Description                  |
| ----------------------- | ------ | ---------------------------- |
| *`resultParse`*         | object | Options object               |
| *`resultParse`*.`path`  | string | athname without the page     |
| *`resultParse`*.`page`  | number | The page number              |
| *`resultParse`*.`query` | string | Object with query parameters |
| *`resultParse`*.`hash`  | string | The hash value (with `#`).   |

#### `libraries.source.stringify()`

Utility for building links from its attributes.

**Syntax**

```typescript
(args: object) => string;
```

**Arguments**

| Name       | Type   | Required | Description                  |
| ---------- | ------ | -------- | ---------------------------- |
| **`path`** | string | yes      | pathname without the page    |
| *`page`*   | number | no       | The page number              |
| *`query`*  | object | no       | Object with query parameters |
| *`hash`*   | string | no       | Thehash value (with `#`).    |

**Return value**

| Name     | Type   | Description     |
| -------- | ------ | --------------- |
| *`link`* | string | Normalized link |

#### `libraries.source.normalize()`

**Syntax**

```typescript
(link: string) => string;
```

**Arguments**

| Name       | Type   | Required | Description                                                               |
| ---------- | ------ | -------- | ------------------------------------------------------------------------- |
| **`link`** | string | yes      | Any link that points to entities in your site (links, custom lists, etc.) |

**Return value**

| Name     | Type   | Description     |
| -------- | ------ | --------------- |
| *`link`* | string | Normalized link |


# @frontity/tiny-router

API reference of \`@frontity/tiny-router\` package

This package is in charge of managing (React) routes in a Frontity project.

## Table of Contents

* [Installation](/frontity-packages/features-packages/tiny-router#installation)
* [Settings](/frontity-packages/features-packages/tiny-router#settings)
  * [`state.router.autoFetch`](/frontity-packages/features-packages/tiny-router#state-router-autofetch)
* [API Reference](/frontity-packages/features-packages/tiny-router#api-reference)
  * [Actions](/frontity-packages/features-packages/tiny-router#actions)
    * [`actions.router.set()`](/frontity-packages/features-packages/tiny-router#actions-router-set)
    * [`actions.router.updateState()`](/frontity-packages/features-packages/tiny-router#actions-router-updatestate)
  * [State](/frontity-packages/features-packages/tiny-router#state)
    * [`state.router.link`](/frontity-packages/features-packages/tiny-router#state-router-link)
    * [`state.router.state`](/frontity-packages/features-packages/tiny-router#state-router-state)

## Installation

Add the `tiny-router` package to your project:

```
npm i @frontity/tiny-router
```

And include it in your `frontity.settings.js` file:

```javascript
module.exports = {
  packages: [
    "@frontity/mars-theme",
    "@frontity/wp-source",
    "@frontity/tiny-router",
  ],
};
```

## Settings

#### `state.router.autoFetch`

When `autoFetch` is activated, tiny-router does a `actions.source.fetch(link)` each time the action `actions.router.set(link)` is triggered. This ensures that the data you need for the current page is always available.

It also does a `actions.source.fetch(link)` in the `beforeSSR` action to ensure that the data needed for SSR is also available.

It's `true` by default.

## API Reference

### Actions

#### `actions.router.set()`

Tiny Router is very simple, it only has one action: `actions.router.set()` .

**Syntax**

```typescript
actions.router.set = async (link: string, options: {
  method: "push" | "replace",
  state: object
}): Promise<void>;
```

**Arguments**

| Name                 | Type   | Required | Description                                                                                                                                                                                                                                                                                                                         |
| -------------------- | ------ | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ***`link`***         | string | yes      | The URL that will replace the current one. *`link` is short for permalink*. Examples:                                                                                                                                                                                                                                               |
| *`options`*          | object | no       | Options object                                                                                                                                                                                                                                                                                                                      |
| *`options`*.`method` | string | -        | The method used in the action. Possible values: `"push"` corresponds to [`window.history.pushState`](https://developer.mozilla.org/en-US/docs/Web/API/History/pushState) and `"replace"` to [`window.history.replaceState`](https://developer.mozilla.org/en-US/docs/Web/API/History/replaceState) \</br> Default Value is `"push"` |
| *`options`*.`state`  | object | -        | An object that will be saved in `window.history.state`. This object is recovered when the user go back and forward using the browser buttons.                                                                                                                                                                                       |

**Examples**

This is a very simple, but functional `Link` component created with `actions.router.set`:

```javascript
const Link = ({ actions, children, link }) => {
  const onClick = (event) => {
    event.preventDefault();
    actions.router.set(link);
  };

  return (
    <a href={link} onClick={onClick}>
      {children}
    </a>
  );
};
```

#### `actions.router.updateState()`

Action that replaces the value of `state.router.state` with the given object. The same object is stored in the browser history state using the [`history.replaceState()`](https://developer.mozilla.org/en-US/docs/Web/API/History/replaceState) function.

**Arguments**

| Name               | Type   | Required | Description                             |
| ------------------ | ------ | -------- | --------------------------------------- |
| **`historyState`** | object | yes      | The object to set as the history state. |

### State

Tiny router has the following state:

#### `state.router.link`

This is the path the site is in. For example, `/category/nature/`.

These are some examples of links:

* `/`: You are in the home, path is `/` and page is `1`.
* `/page/2`: You are in the page 2 of the home, path is `/` and page is `2`.
* `/category/nature:` You are in the category `nature`, path is `/` and page is `1`.
* `/category/nature/page/2`: You are in page 2 of category `nature`, path is `/` and page is `2`.
* `/some-post`: You are a post, path is `/some-post`.
* `/some-page`: You are in a page, path is `/some-page`.

#### `state.router.state`

This is the object that was saved in [`window.history.state`](https://developer.mozilla.org/en-US/docs/Web/API/History/state) when the route was changed.


# @frontity/html2react

API reference of \`@frontity/html2react\` package

This package is in charge of converting HTML to React. It works with [*processors*](/frontity-packages/features-packages/html2react#processors) that match HTML portions and replaces them with React components.

## Table of Contents

* [Installation](/frontity-packages/features-packages/html2react#installation)
* [Settings](/frontity-packages/features-packages/html2react#settings)
* [How to use](/frontity-packages/features-packages/html2react#how-to-use)
  * [Rendering the parsed content](/frontity-packages/features-packages/html2react#rendering-the-parsed-content)
* [Processors](/frontity-packages/features-packages/html2react#processors)
  * [Loading processors](/frontity-packages/features-packages/html2react#loading-processors)
  * [Creating your own processors](/frontity-packages/features-packages/html2react#creating-your-own-processors)
    * [Example](/frontity-packages/features-packages/html2react#example)
  * [Nodes](/frontity-packages/features-packages/html2react#nodes)
* [Default Processors](/frontity-packages/features-packages/html2react#default-processors)
  * [Script](/frontity-packages/features-packages/html2react#script)
    * [Usage](/frontity-packages/features-packages/html2react#usage)
  * [Iframe](/frontity-packages/features-packages/html2react#iframe)
    * [Usage](/frontity-packages/features-packages/html2react#usage)
* [API Reference](/frontity-packages/features-packages/html2react#api-reference)
  * [Libraries](/frontity-packages/features-packages/html2react#libraries)
    * [`libraries.html2react.processors`](/frontity-packages/features-packages/html2react#libraries-html-2-react-processors)
    * [`libraries.html2react.Component`](/frontity-packages/features-packages/html2react#libraries-html-2-react-component)

## Installation

Add the `html2react` package to your project:

```
npm i @frontity/html2react
```

## Settings

This package needs to be included in your `frontity.settings.js` file as one of the packages that will be part of the Frontity project:

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

```javascript
module.exports = {
  packages: ["@frontity/html2react"],
};
```

{% endcode %}

If you use an already created theme this package will already be configured so you don't need to do anything else.

If you're creating a custom theme you'll have to [define the processors you want to use in the configuration of the package](/frontity-packages/features-packages/html2react#loading-processors).

## How to use

### Rendering the parsed content

This is how you need to include the Component that will render the parsed content. The only prop it takes is `html`, and you'll usually pass `post.content.rendered` to it:

```jsx
import React from "react";

const Post = ({ state, libraries }) => {
  const data = state.source.get(state.router.link);
  const post = state.source[data.type][data.id];

  // Component exposed by html2react.
  const Html2React = libraries.html2react.Component;

  return (
    <div>
      <Title />
      <AuthorAndDate />
      <FeaturedImage />
      {/* Use Html2React to render the post HTML content */}
      <Html2React html={post.content.rendered} />
    </div>
  );
};
```

## Processors

Processors are the blocks of logic used by `html2react` to detect specific portions of HTML and return custom HTML or React components.

The `processors` field is an *array* where you can push all the processors you want to use with `html2react`. You can check the default processors [here](/frontity-packages/features-packages/html2react#default-processors).

### Loading processors

You can add your processors directly in [`libraries.html2react.processors`](/frontity-packages/features-packages/html2react#libraries-html-2-react-processors). Here you can see as an example how this is done in `mars-theme`:

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

const myPackage = {
  roots: { ... },
  state: { ... },
  actions: { ... },
  libraries: {
    html2react: {
      processors: [image, customProcessor]
    }
  }
};

export default myPackage;
```

### Creating your own processors

A processor is an object with four properties: `name` , `priority` , `test`,and `processor`.

| Name            | Type     | Required | Description                                                                                                                                                                                                                                                                                                            |
| --------------- | -------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`name`**      | string   | yes      | the name of your processor                                                                                                                                                                                                                                                                                             |
| **`priority`**  | number   | yes      | A number that lets the package know in which order processors should be evaluated. The processors are evaluated in numeric order. For example, a processor with `priority` of `10` will be applied **before** a processor with a `priority` of `20`                                                                    |
| **`test`**      | function | yes      | A function that evaluate each [node](/frontity-packages/features-packages/html2react#nodes), and if it returns `true`, this node will be passed down to the `processor` function                                                                                                                                       |
| **`processor`** | function | yes      | A function to apply some logic to the [node](/frontity-packages/features-packages/html2react#nodes) that we want to modify. It could be substituting HTML tags for React component with some logic, as adding `lazy-loading` to images, or just modifying some attributes, like adding `target="_blank"` to the links. |

Both the `test` and the `processor` functions receive the same arguments `({ node, root, state, libraries })`

| Name        | Type   | Description                                                                                                                                              |
| ----------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `node`      | object | The HTML node tag the processor is evaluating                                                                                                            |
| `root`      | object | The top node of the node tree                                                                                                                            |
| `state`     | object | Access to Frontity's `state` . This could be useful to use some parts of the `state` inside your processor. For example, using your `state.theme.colors` |
| `libraries` | object | Access to Frontity's `libraries`. As it happens with the `state`, sometimes could be useful to access your `libraries` as well                           |

The **`test`** function *returns* a boolean to indicate `processor` function should be executed (the node matches the pattern).

The **`processor`** function *returns* a `node` object.

#### Example

This is how the `image` processor is implemented in `html2react`:

```typescript
import Image from "@frontity/components/image";

const image = {
  // We can add a name to identify it later.
  name: "image",

  // We can add a priority so it executes before or after other processors.
  priority: 10,

  // Only process the node it if it's an image.
  test: ({ node }) => node.component === "img",

  processor: ({ node }) => {
    // If the image is inside a <noscript> tag, we don't want to process it.
    if (node.parent.component === "noscript") return null;

    // Many WP lazy load plugins move the real "src" to "data-src", so we move it back.
    if (node.props["data-src"]) node.props.src = node.props["data-src"];
    if (node.props["data-srcset"])
      node.props.srcSet = node.props["data-srcset"];

    // We tell Html2React that it should use the <Image /> component
    // from @frontity/components, which includes lazy loading support.
    node.component = Image;

    return node;
  },
};

export default image;
```

You don't need to return a React component, you can also modify the attributes (props) of the node. For example, this processor adds `target="_blank"` to the `<a>` tags with href starting with `http`:

```typescript
const extAnchors = {
  name: "external anchors",
  priority: 10,
  // Only process the node it if it's an anchor and href starts with http.
  test: ({ node }) =>
    node.component === "a" && node.props.href.startsWith("http"),
  // Add the target attribute.
  processor: ({ node }) => {
    node.props.target = "_blank";
    return node;
  },
};
```

### Nodes

The object `node` received by both `test` and `processor`can be an `Element`, a `Text` or a `Comment`. You can distinguish between them using `node.type`.

* An `Element` is an HTML tag or a React component.
* A `Text` is a text content. For example, the text inside a `<p>` tag.
* A `Comment` is just an HTML comment. Like this `<!-- comment -->`.

The common properties are:

| Name     | Type    | Description                                                                                                                                                           |        |             |
| -------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------ | ----------- |
| `type`   | string  | The Node type. \</br> Possible values: \`"element"                                                                                                                    | "text" | "comment"\` |
| `parent` | Element | The parent of this node, which is always an `element` (`text` or `comment` can't have children)                                                                       |        |             |
| `ignore` | boolean | If you set `ignore` to `true` for a node, it won't pass any `test`. This is useful in some situations when you don't want additional processors applied to this node. |        |             |

Besides common properties, `Element` nodes are also defined by the following properties:

| Name        | Type                                 | Description                                                                                                                                                                                                  |
| ----------- | ------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `component` | string or function (React component) | If it's a string, it's an HTML tag and if it's a function is a React component. You can change it at will and it is what you would usually do when you want to convert HTML tags to React components         |
| `props`     | object                               | An object containing all the HTML attributes of that node or props of that React component. You can also change them at will. All the attributes are converted to the React equivalents, even for HTML tags. |
| `children`  | array (of nodes)                     | An array containing other nodes, children to this one. If you want to get rid of the children, just overwrite it with `null` or an empty array                                                               |

Examples of `props` values (and their equivalent React props):

* `class` -> `className`
* `style` -> `css`
* `srcset` -> `srcSet`
* `onclick` -> `onClick`
* ..

Besides common properties, `Text` and `Comment` nodes will also have the following property:

| Name      | Type   | Description         |
| --------- | ------ | ------------------- |
| `content` | string | Content of the Node |

## Default Processors

### Script

React doesn’t execute the code inside a `<script>` tags. For that reason, html2react doesn’t execute the script tags included in the contents.

The script processor, with a priority of `20`, processes `<script>` tags found in the HTML for execution. `<script>` type must either be `application/javascript`, `text/javascript` or `application/ecmascript` to pass the test of the processor.

#### Usage

The script processor is included by default in html2react. Therefore, no extra procedure is required to use the processor.

### Iframe

Iframes can impact the loading time and performance of a site. The iframe processor adds lazy-loading to the `<iframe>` tags found in the HTML.

#### Usage

Add `iframe` to the `processors` array in your package `index.js` file.

```javascript
import iframe from "@frontity/html2react/processors/iframe";

const themeName = {
    name: "theme-name",
    ...
    libraries: {
        html2react: {
            processors: [iframe]
        }
    }
}
```

## API Reference

### Libraries

#### `libraries.html2react.processors`

An array of the processors that will be used by `html2react`.

You can add, remove or mutate any processor from the array:

```jsx
// Add a processor.
libraries.html2react.processors.push(image);

// Remove a processor.
const index = libraries.html2react.processors.findIndex(
  (pr) => pr.name === "image"
);
libraries.html2react.processors.splice(index, 1);

// Change a processor priority.
const processor = libraries.html2react.processors.find(
  (pr) => pr.name === "image"
);
processor.priority = 20;
```

#### `libraries.html2react.Component`

The React component used to render the parsed HTML.

**Props**

| Name       | Type   | Required | Description                        |
| ---------- | ------ | -------- | ---------------------------------- |
| **`html`** | string | yes      | The HTML that needs to be rendered |

```jsx
import React from "react";

const Post = ({ libraries }) => {
  // Get the component exposed by html2react.
  const Html2React = libraries.html2react.Component;

  return (
    <>
      {/* Use it to render the HTML. */}
      <Html2React html={html} />
    </>
  );
};
```


# @frontity/head-tags

API reference of \`@frontity/head-tags\` package

This package is designed to get automatically all the metadata that the [REST API Head Tags plugin](https://wordpress.org/plugins/rest-api-head-tags/) exposes in the REST API (SEO metadata from plugins like Yoast SEO or All in One SEO), and **add them as meta tags in the `<head>` section of the rendered page**.

{% hint style="warning" %}
This package won't work without [REST API Head Tags plugin](https://wordpress.org/plugins/rest-api-head-tags/) installed and activated in your WordPress backend, so make sure you have it before using this package.
{% endhint %}

{% hint style="info" %}
If you are using Yoast SEO >v14.0 we recommend that you instead use the [@frontity/yoast](/frontity-packages/features-packages/yoast) package which does not require an additional plugin to be installed in WordPress.
{% endhint %}

## Table of Contents

* [Installation](/frontity-packages/features-packages/head-tags#installation)
* [Settings](/frontity-packages/features-packages/head-tags#settings)
* [How to use](/frontity-packages/features-packages/head-tags#how-to-use)
* [API Reference](/frontity-packages/features-packages/head-tags#api-reference)
  * [State](/frontity-packages/features-packages/head-tags#state)
    * [`headTags.get`](/frontity-packages/features-packages/head-tags#headtags-get)

## Installation

Add the `head-tags` package to your project:

```
npm i @frontity/head-tags
```

Do this in your root and include it in your `frontity.settings.js` file:

```javascript
...
packages: [
    "@frontity/mars-theme",
    "@frontity/tiny-router",
    ...
    "@frontity/head-tags"
]
...
```

{% hint style="warning" %}
If you have an existing project make sure your [@frontity/wp-source](/frontity-packages/features-packages/wp-source) package is at least on the 1.5.0 version. If not, update it using this command: `> npm install @frontity/wp-source@latest`.
{% endhint %}

## Settings

As it works automatically, It doesn't have settings itself, but it requires two Frontity parameters to work:

* `state.frontity.url` : The URL of your site. Usually defined in the `frontity.settings.js` file.
* `state.source.url` or `state.source.api`: The API where your project is pointing. Defined at [@frontity/wp-source](/frontity-packages/features-packages/wp-source#settings) if you haven't changed your Source.

It needs `@frontity/wp-source` installed and updated to at least the `1.5.0` version.

## How to use

This package will automatically add all the meta tags defined in WordPress for the page (through plugins like Yoast SEO or All in One SEO) in the `<head>` section of the rendered page. So there are no additional steps to do. Just install the package and everything will work out of the box.

Remember that you'll need the [REST API Head Tags plugin](https://wordpress.org/plugins/rest-api-head-tags/) installed in your WordPress. With that, this package will take care of the rest.

If you want to access the metadata available for a specific link you can use the [`headTags.get`](/frontity-packages/features-packages/head-tags#headtags-get) method.

## API Reference

### State

#### `headTags.get`

It is a function that accepts a `link`as parameter and it returns an array with the `head_tags` field of that link.

```javascript
state.headTags.get("/blog/hello-world/");
```

will return something like

```javascript
[
  {
    tag: "title",
    content: "Hello world! - My Site",
  },
  {
    tag: "meta",
    attributes: {
      name: "robots",
      content: "max-snippet:-1, max-image-preview:large, max-video-preview:-1",
    },
  },
  {
    tag: "link",
    attributes: {
      rel: "canonical",
      href: "http://mysite.com/hello-world/",
    },
  },
];
```


# @frontity/yoast

API reference for the \`@frontity/yoast\` package

This package is designed to automatically get and render all the tags exposed in the REST API by the [Yoast SEO plugin for WordPress](https://wordpress.org/plugins/wordpress-seo/). It works with Yoast SEO version 14.0 or later.

{% hint style="warning" %}
Please note that this package will **not** work with versions of the Yoast SEO plugin prior to version 14.0.
{% endhint %}

{% hint style="info" %}
If you have an earlier version of the Yoast SEO plugin (i.e. < 14.0) installed in WordPress, or you have installed another SEO package that doesn't add head tags to the REST API, then you should use the [`@frontity/head-tags`](https://www.npmjs.com/package/@frontity/head-tags) package instead. In this case you will also need the [REST API Head Tags plugin](https://wordpress.org/plugins/rest-api-head-tags/).

See the [`@frontity/head-tags` documentation](https://api.frontity.org/frontity-packages/features-packages/head-tags) for more information.
{% endhint %}

## Table of Contents

* [Installation](/frontity-packages/features-packages/yoast#installation)
* [Settings](/frontity-packages/features-packages/yoast#settings)
  * [`state.yoast.renderTags`](/frontity-packages/features-packages/yoast#state-yoast-rendertags)
  * [`state.yoast.transformLinks`](/frontity-packages/features-packages/yoast#state-yoast-transformlinks)
* [Usage](/frontity-packages/features-packages/yoast#usage)
  * [Adding the Yoast meta to archive pages](/frontity-packages/features-packages/yoast#adding-the-yoast-meta-to-archive-pages)
* [Video](/frontity-packages/features-packages/yoast#video)

## Installation

Add the `@frontity/yoast` package to your project:

```bash
npm i @frontity/yoast
```

> **NOTE:** This package requires the [Yoast SEO](https://wordpress.org/plugins/wordpress-seo/) plugin (v14.0 or above) to be installed and activated on the WordPress site in order to function.

Once installed it should be included in your `frontity.settings.js`

```javascript
export default {
  packages: ["@frontity/yoast"],
};
```

## Settings

The [namespace](https://docs.frontity.org/learning-frontity/namespaces) for this package is **`yoast`**.

#### `state.yoast.renderTags`

Possible values:

* **both** (default) - Render the Yoast meta tags in both the server and the client
* **server** - Render the Yoast meta tags only in the server.

With the "server" option active, the Yoast meta tags are only included in the HTML generated by the Frontity server and so the tags are only generated if you go to the page source.

With the "both" option active, as well as being rendered in the server, the Yoast meta tags are rendered in the client as the site is navigated.

Selecting "server" shouldn’t affect the SEO of your site as Google does not do client-side navigation, Google is only concerned with server side page rendering .

The "server" option can be used to improve the client-side perfomance, as the `<Html2React>` component which is used to render the meta tags can be processor intensive.

Even if "server" is selected, thereby causing the rest of the meta tags to only be rendered in the server, the `<title>` tag continues to be rendered in the client while the site is being navigated so that the current page/post title will be displayed in the browser tab. Althougth the `<Html2React>` is processor intensive it is not used to render the title tag, so client-side performance will not be impacted.

#### `state.yoast.transformLinks`

Defaults to `false`.

Used if you are using Frontity in [Decoupled Mode](https://docs.frontity.org/architecture/decoupled-mode). If you are using Frontity in [Embedded Mode](https://docs.frontity.org/architecture/embedded-mode) this property must be set to false.

If you are using Frontity in Decoupled Mode this setting defines a set of properties to transform links present in the yoast\_head field.

Example:

```javascript
{
  name: "@frontity/yoast",
  state: {
    yoast: {
      transformLinks: {
        ignore: "^(wp-(json|admin|content|includes))|feed|comments|xmlrpc",
        base: "https://wp.mysite.com",
      },
    },
  },
}
```

| Name     | Type   | Required | Description                                                                                                                                                          |
| -------- | ------ | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `ignore` | string | optional | RegExp in string format that defines a set of links that must not be transformed.                                                                                    |
| `base`   | string | optional | WordPress URL base that must be replaced by the Frontity URL base (specified in state.frontity.url). If this value is not set, it is computed from state.source.api. |

## Usage

The `@frontity/yoast` package also requires two Frontity parameters in order to work:

* `state.frontity.url` : The URL of your site. Usually defined in the `frontity.settings.js` file.
* `state.source.url`: The WordPress API that is the source of your data. Defined at [@frontity/wp-source](https://api.frontity.org/frontity-packages/features-packages/wp-source#settings).

### Adding the Yoast meta to archive pages

As it stands the `@frontity/yoast` package adds the Yoast meta to pages, and to single posts and CPTs. In order to have the Yoast SEO meta on post/CPT archive pages the following PHP code snippet should be added to the WordPress installation. It can be added either in the active theme's `functions.php` file or by using a plugin such as [Code Snippets](https://en-gb.wordpress.org/plugins/code-snippets/).

```php
add_action( 'rest_api_init', function () {
  foreach ( get_post_types( array( 'show_in_rest' => true ), 'objects' ) as $post_type ) {
    if ( 'post' === $post_type->name || $post_type->has_archive ) {
      add_filter( "rest_prepare_{$post_type->name}", function ( $response ) {
        $type      = $response->data['type'];
        $types_url = rest_url( "wp/v2/types/$type" );

        $response->add_links(
          array(
            'type' => array(
              'href'       => $types_url,
              'embeddable' => true,
            ),
          )
        );

        return $response;
      } );
    }
  }
} );
```

This snippet embeds the post types – i.e. the entities that contain the `yoast_meta` field for post/CPT archives – in the REST API responses. It adds the `type` property inside the `\_links` field of post entities when the `?_embed=true` query parameter is used.

> Note: Frontity always uses the `?_embed=true` query parameter when making requests to the WP REST API.

## Video

This short video demonstrates the usage of the `@frontity/yoast` package.

{% embed url="<https://www.youtube.com/watch?v=nqXl-2zC9Eo>" %}


# @frontity/google-ad-manager

API reference of \`@frontity/google-ad-manager\` package

This package enables Frontity to integrate with Google Ad Manager. It allows you to add ads as **fills** in `frontity.settings.js` so that they will appear in a specific **slot** defined in your theme. See the [Slot and Fill](/frontity-packages/core-package/frontity#slot) documentation for more information.

## Table of Contents

* [Installation](/frontity-packages/features-packages/google-ad-manager#installation)
* [Settings](/frontity-packages/features-packages/google-ad-manager#settings)
  * [Object properties](/frontity-packages/features-packages/google-ad-manager#object-properties)
    * [The `props` property](/frontity-packages/features-packages/google-ad-manager#the-props-property)
* [Examples](/frontity-packages/features-packages/google-ad-manager#examples)
* [Usage](/frontity-packages/features-packages/google-ad-manager#usage)
  * [Using the `Slot & Fill` pattern](/frontity-packages/features-packages/google-ad-manager#using-the-slot-and-fill-pattern)
  * [Using the Ad component directly](/frontity-packages/features-packages/google-ad-manager#using-the-ad-component-directly)
* [Video](/frontity-packages/features-packages/google-ad-manager#video)

## Installation

Add the `google-ad-manager` package to your project:

```bash
npm i @frontity/google-ad-manager
```

## Settings

This package can be included in your `frontity.settings.js` file as one of the packages that will be part of your Frontity project.

The [namespace](https://docs.frontity.org/learning-frontity/namespaces) for this package is **`googleAdManager`**. The object should be added to `state.fills`.

Each fill in the **`googleAdManager`** namespace is an object which should be assigned to an arbitrarily named key. The structure should be as follows:

```javascript
export default {
  packages: [
    {
      name: "@frontity/google-ad-manager",
      state: {
        fills: {
          googleAdManager: {
            arbitrary_fill_name: {
              // Object properties
            },
          },
        },
      },
    },
  ],
};
```

### Object properties

| Name          | Type   | Required | Description                                                                                                                                                                              |
| ------------- | ------ | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`slot`**    | string | yes      | The name of the slot as defined in your theme where you want the ad to go.                                                                                                               |
| **`library`** | string | yes      | The React component used to display the Ad. We can set this value to `"googleAdManager.GooglePublisherTag"` (`GooglePublisherTag` component available in the `googleAdManager` package). |
| `priority`    | int    | no       | Assigns a priority in case more than one fill is assigned to that slot.                                                                                                                  |
| **`props`**   | obj    | yes      | Props that will be passed to the `<Slot>` component *(see table below)*                                                                                                                  |

#### The `props` property

An object with props that will be passed to the `<Slot>` component.

| Name        | Type   | Required | Description                                                                                                                                                                                              |
| ----------- | ------ | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`id`**    | string | yes      | An `id` for Ad, used to generate the ID the `<div>` container will use.                                                                                                                                  |
| **`unit`**  | string | yes      | The (Google supplied) adUnitPath code for the ad unit to be displayed. [*more info*](https://developers.google.com/publisher-tag/reference#googletag.slot-googletag.defineslotadunitpath,-size,-opt_div) |
| **`size`**  | object | yes      | An array of integer values to specify the width and height (in pixels) to display the ad.                                                                                                                |
| `targeting` | object | no       | One or more keys, each with one or more associated values. [*more info*](https://developers.google.com/publisher-tag/guides/key-value-targeting).                                                        |
| `data`      | object | no       | Data object representing a link, passed automatically if the component is rendered by a slot.                                                                                                            |

## Examples

Example with one ad:

```javascript
export default {
  packages: [
    {
      name: "@frontity/google-ad-manager",
      state: {
        fills: {
          googleAdManager: {
            belowHeaderAd: {
              slot: "Below Header",
              library: "googleAdManager.GooglePublisherTag",
              priority: 5,
              props: {
                id: "div-gpt-below-header",
                unit: "/6499/example/banner",
                size: [320, 100],
              },
            },
          },
        },
      },
    },
  ],
};
```

If you need to add more than one ad you can give each object in the `state.fills.googleAdManager` object it's own key:

```javascript
export default {
  packages: [
    {
      name: "@frontity/google-ad-manager",
      state: {
        fills: {
          googleAdManager: {
            belowHeaderAd: {
              slot: "Below Header",
              library: "googleAdManager.GooglePublisherTag",
              priority: 5,
              props: {
                id: "div-gpt-below-header",
                unit: "/6499/example/banner",
                size: [320, 100],
              },
            },
            belowContentAd: {
              slot: "Below Content",
              library: "googleAdManager.GooglePublisherTag",
              priority: 5,
              props: {
                id: "div-gpt-below-content",
                unit: "/6499/example/banner",
                size: [300, 600],
                targeting: {
                  interests: ["sports", "music", "movies"],
                },
              },
            },
          },
        },
      },
    },
  ],
};
```

## Usage

### Using the `Slot & Fill` pattern

The recommended usage of this component is using the Slot and Fill pattern. The configuration of the fill(s) is done in the `state.fills.googleAdManager` namespace in `frontity.settings.js` as explained above.

With this configuration we can then insert the Slots representing the Ads in any React component.

```jsx
import { Slot, ... } from "frontity";

const MyComponent = () => {

  return (
    <>
      ...
      <Slot name="Below Header" />
      ...
      <Slot name="Below Content" />
      ...
    </>
  );
};

...

export default MyComponent;
```

### Using the Ad component directly

Alternatively, since the Ad component is exposed in `libraries`, you can get the `GooglePublisherTag` component from `libraries` and render it wherever you wish.

```jsx
const MyComponent = ({ libraries }) => {
  const MyAd = libraries.fills.googleAdManager.GooglePublisherTag;

    return (
      <MyAd
      unit="/unit/234"
      size={[300, 600]}
        />
    );
};

export connect(MyComponent);
```

## Video

This short video demonstrates the usage of the `@frontity/google-ad-manager` package.

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


# @frontity/smart-adserver

API reference of \`@frontity/smart-adserver\` package

Smart Adserver is an ad serving network and they provide an API for displaying the ads which is described [here](https://support.smartadserver.com/s/article/Tagging-guide).

The `@frontity/smart-adserver` package will load a third-party Smart Adserver library which adds certain properties on the global `window` object. Then you as the developer can render the exposed `<SmartAd>` component, which will use those properties to make the "ad call" (which are basically API calls to the Smart Adserver).

In response, the Smart Adserver dynamically loads some code which will modify the DOM to insert the ad in the place that the `<SmartAd>` component was rendered.

The package has 3 main components:

* *The "Root" component*. It includes the `<Head>` that loads the Smart Adserver library. When the user adds the `@frontity/smart-adserver` to their `frontity.settings.js` file, this library will be loaded automatically.
* *The `SmartAd` component*. This component is exposed in `libraries.fills.SmartAdserver.SmartAd`. The users can just use this component directly to display ads by passing it relevant props. The component takes care of calling the Smart Adserver API and injecting the ad into the DOM in the relevant place
* *Ability to specify the ads in `fills` in the `frontity.settings.js` file.* Ads can be placed in specific slots in a theme by using that approach.

## Table of Contents

* [Installation](/frontity-packages/features-packages/smart-ads#installation)
* [Settings](/frontity-packages/features-packages/smart-ads#settings)
  * [Object properties](/frontity-packages/features-packages/smart-ads#object-properties)
    * [The `props` property](/frontity-packages/features-packages/smart-ads#the-props-property)
* [Examples](/frontity-packages/features-packages/smart-ads#examples)
* [Usage](/frontity-packages/features-packages/smart-ads#usage)
  * [Using the `Slot & Fill` pattern](/frontity-packages/features-packages/smart-ads#using-the-slot-fill-pattern)
  * [Using the Ad component directly](/frontity-packages/features-packages/smart-ads#using-the-ad-component-directly)

## Installation

The package can be installed like:

```bash
npm i @frontity/smart-adserver
```

## Settings

This package can be included in your `frontity.settings.js` file as one of the packages that will be part of your Frontity project.

The [namespace](https://docs.frontity.org/learning-frontity/namespaces) for this package is **`smartAdserver`**. To use the [Slot and Fill](https://api.frontity.org/frontity-packages/core-package/frontity#slot) pattern with this package we should add a settings object to `state.fills` under the `smartAdserver` namespace.

Each [fill](https://api.frontity.org/frontity-packages/core-package/frontity#fills) in the **`smartAdserver`** namespace is an object which should be assigned to an arbitrarily named key. The structure should be as follows:

```javascript
export default {
  packages: [
    {
      name: "@frontity/smart-adserver",
      state: {
        fills: {
          smartAdserver: {
            arbitrary_fill_name: {
              // Object properties
            },
          },
        },
      },
    },
  ],
};
```

### Object properties

To define a SmartAd using the [Slot & Fills](https://api.frontity.org/frontity-packages/core-package/frontity#slot) pattern we use [the standard *FilL* properties](https://api.frontity.org/frontity-packages/core-package/frontity#fills)

| Name          | Type   | Required | Description                                                                                                                                                    |
| ------------- | ------ | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`slot`**    | string | yes      | The name of the slot as defined in your theme where you want the ad to go.                                                                                     |
| **`library`** | string | yes      | The React component used to display the Ad. We can set this value to `"smartAdserver.SmartAd"` (`SmartAd` component available in the `smartAdserver` package). |
| `priority`    | int    | no       | Assigns a priority in case more than one fill is assigned to that slot.                                                                                        |
| **`props`**   | obj    | yes      | Props that will be passed to the `<Slot>` component *(see table below)*                                                                                        |

#### The `props` property

An object with props that will be passed to the `<Slot>` component.

| Name            | Type                                                                                 | Required | Description                                                                                                                                                                                                                                                       |
| --------------- | ------------------------------------------------------------------------------------ | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`siteId`**    | number                                                                               | yes      | The `id` of the site as defined in [SmartAds](https://support.smartadserver.com/s/article/Ad-API-reference); represents a website or mobile application; [*more info*](https://support.smartadserver.com/s/article/Setting-up-inventory)                          |
| **`pageId`**    | number                                                                               | yes      | The `id` of the page as defined in [SmartAds](https://support.smartadserver.com/s/article/Ad-API-reference); represents a website or mobile application; [*more info*](https://support.smartadserver.com/s/article/Setting-up-inventory)                          |
| **`formatId`**  | number                                                                               | yes      | The `id` of the format as defined in [SmartAds](https://support.smartadserver.com/s/article/Ad-API-reference); represents an ad slot on a page (medium rectangle, skyscraper...); [*more info*](https://support.smartadserver.com/s/article/Setting-up-inventory) |
| **`callType`**  | string                                                                               | yes      | The type of the ad call. Possible values: `iframe` or `std`                                                                                                                                                                                                       |
| **`tagId`**     | string                                                                               | no       | The `id` of the container that will contain the ad. Default Value: `sas_${formatId}"`                                                                                                                                                                             |
| **`width`**     | number                                                                               | no       | The width of the ad. Used with callType `iframe`.                                                                                                                                                                                                                 |
| **`height`**    | number                                                                               | no       | The height of the ad. Used with callType `iframe`.                                                                                                                                                                                                                |
| **`minHeight`** | number                                                                               | no       | Minimum height of the container for the ad. Used with callType `std`.                                                                                                                                                                                             |
| **`css`**       | [style object](https://api.frontity.org/frontity-packages/core-package/frontity#css) | no       | The optional styles that can be passed to the SmartAd component via `css` prop. They will be merged with the default styles of the SmartAd component. [*more info*](https://api.frontity.org/frontity-packages/core-package/frontity#css)                         |
| **`target`**    | string                                                                               | no       | Keyword targeting allows you to display ads only when specific keywords or key/value pairs are passed in the ad request. [*more info*](https://support.smartadserver.com/s/article/Using-keyword-targeting)                                                       |

## Examples

```javascript
module.exports = {
  packages: [
    ...,
    {
      name: "@frontity/smart-adserver",
      state: {
        // Global settings.
        smartAdserver: {
          networkId: 620,
          subdomain: "www8",
        },
        fills: {
          smartAdserver: {
            // This ad is using the 'std' call: https://support.smartadserver.com/s/article/Tagging-guide
            stdAd: {
              slot: "header",
              library: "smartAdserver.SmartAd",
              props: {
                callType: "std",
                siteId: 103409,
                pageId: 659846,
                formatId: 14968,
                tagId: "below-header-14968", // The id of the container where we render the ad.
                minHeight: 100, // In px, optional.
              },
            },
            // This ad is using the 'iframe' call: https://support.smartadserver.com/s/article/Tagging-guide
            iframeAd: {
              slot: "content",
              library: "smartAdserver.SmartAd",
              props: {
                siteId: 103409,
                pageId: 659846,
                formatId: 14968,
                tagId: "below-content-14968",
                width: 300, // Should be specified if callType === 'iframe'.
                height: 600, // Should also be specified if callType === 'iframe'.
              },
            },
          },
        },
      },
    },
  ],
};
```

## Usage

### Using the `Slot & Fill` pattern

The recommended usage of this component is using the [Slot and Fill](https://api.frontity.org/frontity-packages/core-package/frontity#slot) pattern. The configuration of the fill(s) is done in the `state.fills.smartAdserver` namespace in `frontity.settings.js` as explained above.

With this configuration we can then insert the Slots representing the Ads in any React component.

```jsx
import { Slot, ... } from "frontity";

const MyComponent = () => {

  return (
    <>
      ...
      <Slot name="header" />
      ...
      <Slot name="content" />
      ...
    </>
  );
};

...

export default MyComponent;
```

### Using the Ad component directly

Alternatively, since the Ad component is exposed in `libraries`, you can get the `SmartAd` component from `libraries` and render it wherever you wish.

```jsx
const MyComponent = ({ libraries, ...props }) => {
  const MySmartAd = libraries.fills.smartAdserver.SmartAd;
  const {siteId, pageId, formatId} = props
    return (
      <MySmartAd
        callType="std"
        siteId={siteId}
        pageId={pageId}
        formatId={formatId}
        tagId="test-smartad"
        css={css`
          border: 5px solid dotted;
        `}
      />
    );
};

export connect(MyComponent);
```


# analytics packages

There is a set of official *Analytics Frontity packages* that you can use to easily add web analytics services to your project.

These packages are:

* [`@frontity/google-analytics`](/frontity-packages/features-packages/analytics/google-analytics) for data tracking using [Google Analytics](https://analytics.google.com/)
* [`@frontity/google-tag-manager-analytics`](/frontity-packages/features-packages/analytics/google-tag-manager-analytics) for data tracking using [Google Tag Manager](https://tagmanager.google.com/)
* [`@frontity/comscore-analytics`](/frontity-packages/features-packages/analytics/comscore-analytics) for data tracking using [Comscore](https://www.comscore.com/)

## Table of Contents

* [Installation](/frontity-packages/features-packages/analytics#installation)
* [Settings](/frontity-packages/features-packages/analytics#settings)
  * [`state.analytics.pageviews`](/frontity-packages/features-packages/analytics#state-analytics-pageviews)
  * [`state.analytics.events`](/frontity-packages/features-packages/analytics#state-analytics-events)
* [How to use](/frontity-packages/features-packages/analytics#how-to-use)
  * [`actions.analytics.pageview`](/frontity-packages/features-packages/analytics#actions-analytics-pageview)
  * [`actions.analytics.event`](/frontity-packages/features-packages/analytics#actions-analytics-event)

## Installation

Install the analytics package you need for your project:

* [Installation instructions for `@frontity/google-analytics`](/frontity-packages/features-packages/analytics/google-analytics#install)
* [Installation instructions for `@frontity/google-tag-manager-analytics`](/frontity-packages/features-packages/analytics/google-tag-manager-analytics#install)
* [Installation instructions for `@frontity/comscore-analytics`](/frontity-packages/features-packages/analytics/comscore-analytics#install)

## Settings

Each package will require some custom configuration to add things such as the tracking IDs for the services behind. In the description of each package you'll find the details of each configuration:

* [Settings for `@frontity/google-analytics`](/frontity-packages/features-packages/analytics/google-analytics#settings)
* [Settings for `@frontity/google-tag-manager-analytics`](/frontity-packages/features-packages/analytics/google-tag-manager-analytics#settings)
* [Settings for `@frontity/comscore-analytics`](/frontity-packages/features-packages/analytics/comscore-analytics#settings)

Once we have properly installed and configured these `analytics` packages, their actions will be centralized by the `analytics` namespace.

In `frontity.settings.js` we can enable/disable specific analytics packages for pageviews or events through the following properties in the `state` (under the `analytics` namespace):

* `state.analytics.pageviews`
* `state.analytics.events`

These properties can be set directly in `frontity.settings.js` from `state.analytics`...

```javascript
const settings = {
  name: ...,
  state: {
    frontity: {...},
    analytics: {
      pageviews: {
        googleAnalytics: false,
        comscoreAnalytics: true,
      },
      events: {
        googleAnalytics: true,
        comscoreAnalytics: false,
      }
    },
  },
  packages: [{...}, {...}]
};

export default settings;
```

Or from each Analytics package setting...

```javascript
const settings = {
  ...,
  packages: [
    {
      name: "@frontity/google-analytics",
      state: {
        analytics: {
          pageviews: { googleAnalytics: true },
          events: { googleAnalytics: true }
        },
      },
    },
    {
      name: "@frontity/comscoreAnalytics",
      state: {
        analytics: {
          pageviews: { comscoreAnalytics: false },
          events: { comscoreAnalytics: false }
        },
      },
    },
    ...
  ],
};
export default settings;
```

### `state.analytics.pageviews`

Map of Analytics packages namespaces with boolean values.

This object is used by `actions.analytics.pageview` to know which analytics packages should send the pageview to their respective services.

If you want to disable sending pageviews for a specific analytics package, the respective namespace of that package should be set here to `false`.

{% hint style="info" %}
All analytics namespaces will be `true` by default in this setting.
{% endhint %}

### `state.analytics.events`

Map of Analytics packages namespaces with boolean values.

This object is used by `actions.analytics.event` to know which analytics packages should send the event to their respective services.

If you want to disable sending events for a specific analytics package, the respective namespace of that package should be set here to `false`.

{% hint style="info" %}
All analytics namespaces will be `true` by default in this setting.
{% endhint %}

## How to use

Once everything is properly configured, the following `actions` under the namespace `analytics` will be ready to be used:

* `actions.analytics.pageview`
* `actions.analytics.event`

### `actions.analytics.pageview`

Send a pageview to all active analytics packages.

This action takes all namespaces defined in `state.analytics.pageviews` that are `true` and calls the `pageview` action of each one with the specified `Pageview` object.

`actions.analytics.pageview` is automatically launched every time link changes (or every time `action.router.set(link)` is launched).

{% hint style="warning" %}
This action is is not meant to be called directly but in case you still want to do this it would be something like this:

```javascript
actions.analytics.pageview({
  link: "/2016/the-beauties-of-gullfoss",
  title: "The Beauties Of Gullfoss",
});
```

{% endhint %}

### `actions.analytics.event`

Send an event to all enabled analytics packages.

This action takes all namespaces defined in `state.analytics.events` that are `true` and calls the `event` action of each one with the specified `Event` object.

This is the method you can call from any component of your React app to track specific events.

*Example:*

```javascript
actions.analytics.event({
  name: "click",
  payload: {
    category: "video",
    label: "featured-media",
  },
});
```

The `actions.analytics.event()` must receive an event object with the following properties.

| Name          | Type   | Required | Description                                                                             |
| ------------- | ------ | -------- | --------------------------------------------------------------------------------------- |
| **`name`**    | string | yes      | The value of this property is mapped to the proper name event of each analytics package |
| **`payload`** | object | yes      | Event payload.                                                                          |

This method will send the event tracking information to all the packages enabled in `state.analytics.events`.

Each package will handle the information sent through this `actions.analytics.event()` in a different way:

* [How `@frontity/google-analytics` handles this event object](/frontity-packages/features-packages/analytics/google-analytics#actions-analytics-event)
* [How `@frontity/google-tag-manager-analytics` handles this event object](/frontity-packages/features-packages/analytics/google-tag-manager-analytics#actions-analytics-event)
* [How `@frontity/comscore-analytics` handles this event object](/frontity-packages/features-packages/analytics/comscore-analytics#actions-analytics-event)


# @frontity/google-analytics

Analytics package to use [Google Analytics](https://analytics.google.com/) with Frontity

## Table of Contents

* [Install](/frontity-packages/features-packages/analytics/google-analytics#install)
* [Settings](/frontity-packages/features-packages/analytics/google-analytics#settings)
* [Usage](/frontity-packages/features-packages/analytics/google-analytics#usage)
  * [`actions.analytics.pageview`](/frontity-packages/features-packages/analytics/google-analytics#actions-analytics-pageview)
  * [`actions.analytics.event`](/frontity-packages/features-packages/analytics/google-analytics#actions-analytics-event)

## Install

```bash
npm i @frontity/google-analytics
```

## Settings

The [namespace](https://docs.frontity.org/learning-frontity/namespaces) for this package is **`googleAnalytics`**

Every Google Analytics account has a [Tracking ID](https://support.google.com/analytics/answer/7372977?hl=en).\
To connect the package with a specific account (or accounts) we can set the following properties in the `frontity.settings.js`:

* `state.googleAnalytics.trackingId`: to specify just one *tracking ID*
* `state.googleAnalytics.trackingIds`: to specify a list of tracking ID's

```javascript
export default {
  packages: [
    {
      name: "@frontity/google-analytics",
      state: {
        googleAnalytics: {
          trackingId: "UA-12345678-9",
        },
      },
    },
  ],
};
```

```javascript
export default {
  packages: [
    {
      name: "@frontity/google-analytics",
      state: {
        googleAnalytics: {
          trackingIds: ["UA-34567890-12", "UA-34567890-13"],
        },
      },
    },
  ],
};
```

## Usage

This `@frontity/google-analytics` package can co-exist with some other `analytics` packages. Once we have properly installed and configured these `analytics` packages, their actions will be centralized by the `analytics` namespace

* `actions.analytics.pageview()` will take into account settings in `state.analytics.pageviews`
* `actions.analytics.event()` will take into account settings in `state.analytics.events`

> Read more [here](/frontity-packages/features-packages/analytics#how-to-use) about how to use Analytic packages

### `actions.analytics.pageview`

If `@frontity/google-analytics` is configured and enabled for *pageviews* in `state.analytics.pageviews`, every time a link changes (or every time `action.router.set(link)` is launched) a tracking for that page will be sent to Google Analytics by using internally `actions.analytics.pageview()`

### `actions.analytics.event`

If `@frontity/google-analytics` is configured and enabled for *events* in `state.analytics.events`, every time you call the method `actions.analytics.event()` from any of your React components, the proper tracking info will be sent to Google Analytics.

The `actions.analytics.event()` must receive an event object with the following properties.

| Name          | Type   | Required | Description                                                                                                                                                                                       |
| ------------- | ------ | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`name`**    | string | yes      | The value of this property is mapped to the [`eventAction`](https://developers.google.com/analytics/devguides/collection/analyticsjs/field-reference#eventAction) field of `analytics.js` events. |
| **`payload`** | object | yes      | Event payload.                                                                                                                                                                                    |

The `payload` object has to have the following format:

| Name           | Type   | Required | Description                                                                                                                                                                                           |
| -------------- | ------ | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`category`** | string | yes      | The value of this property is mapped to the [`eventCategory`](https://developers.google.com/analytics/devguides/collection/analyticsjs/field-reference#eventCategory) field of `analytics.js` events. |
| `label`        | string | no       | The value of this property is mapped to the [`eventLabel`](https://developers.google.com/analytics/devguides/collection/analyticsjs/field-reference#eventLabel) field of `analytics.js` events.       |
| `value`        | number | no       | The value of this property is mapped to the [`eventValue`](https://developers.google.com/analytics/devguides/collection/analyticsjs/field-reference#eventValue) field of `analytics.js` events.       |
| `[key]`        | any    | no       | Any other property specified in [`analytics.js` field reference](https://developers.google.com/analytics/devguides/collection/analyticsjs/field-reference).                                           |

These values will be transfomed (by this package) into the proper format before sending the data to Google Analytics


# @frontity/google-tag-manager-analytics

Analytics package to use [Google Tag Manager](https://tagmanager.google.com/) with Frontity

## Table of Contents

* [Install](/frontity-packages/features-packages/analytics/google-tag-manager-analytics#install)
* [Settings](/frontity-packages/features-packages/analytics/google-tag-manager-analytics#settings)
* [Usage](/frontity-packages/features-packages/analytics/google-tag-manager-analytics#usage)
  * [`actions.analytics.pageview`](/frontity-packages/features-packages/analytics/google-tag-manager-analytics#actions-analytics-pageview)
  * [`actions.analytics.event`](/frontity-packages/features-packages/analytics/google-tag-manager-analytics#actions-analytics-event)

## Install

```bash
npm i @frontity/google-tag-manager-analytics
```

## Settings

The [namespace](https://docs.frontity.org/learning-frontity/namespaces) for this package is **`googleTagManagerAnalytics`**

Every Google Tag Manager account has a [Container ID](https://support.google.com/tagmanager/answer/6103696?hl=en).\
To connect the package with a specific account (or accounts) we can set the following properties in the `frontity.settings.js`:

* `state.googleTagManagerAnalytics.containerId`: to specify just one *container ID*
* `state.googleTagManagerAnalytics.containerIds`: to specify a list of *container ID's*

```javascript
export default {
  packages: [
    {
      name: "@frontity/google-tag-manager-analytics",
      state: {
        googleTagManagerAnalytics: {
          containerId: "GTM-BCDFGHJ",
        },
      },
    },
  ],
};
```

```javascript
export default {
  packages: [
    {
      name: "@frontity/google-tag-manager-analytics",
      state: {
        googleTagManagerAnalytics: {
          containerIds: ["GTM-BCDFGHJ", "GTM-HJSFDUF"],
        },
      },
    },
  ],
};
```

## Usage

This `@frontity/google-tag-manager-analytics` package can co-exist with some other `analytics` packages. Once we have properly installed and configured these `analytics` packages, their actions will be centralized by the `analytics` namespace

* `actions.analytics.pageview()` will take into account settings in `state.analytics.pageviews`
* `actions.analytics.event()` will take into account settings in `state.analytics.events`

> Read more [here](/frontity-packages/features-packages/analytics#how-to-use) about how to use Analytic packages

### `actions.analytics.pageview`

If `@frontity/google-tag-manager-analytics` is configured and enabled for *pageviews* in `state.analytics.pageviews`, every time a link changes (or every time `action.router.set(link)` is launched) a tracking for that page will be sent to Google Tag Manager.

#### Sending `pageviews` to Google Analytics via Google Tag Manager

In order to send pageviews to Google Analytics through Google Tag Manager in a Frontity project you have to create a Trigger listening to a **custom event named `pageview`**, instead of the *default `pageview`* ([the default Event Type `pageview`, doesn't work properly in Isomorphic Apps](https://github.com/frontity/docs/issues/262#issuecomment-822417769)). This custom event is automatically send by `@frontity/google-tag-manager-analytics package`

**Trigger**

![](https://frontity.org/wp-content/uploads/2021/04/google-tag-manager-custom-event.png)

**Tag**

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

{% hint style="info" %}
In the [Feature Discussion of this package](https://community.frontity.org/t/google-tag-manager-package/1400) you have [the format sent internally](https://community.frontity.org/t/google-tag-manager-package/1400/18) just in case you need it for your [own customizations](https://github.com/frontity/docs/issues/262#issuecomment-822426997)
{% endhint %}

### `actions.analytics.event`

If `@frontity/google-tag-manager-analytics` is configured and enabled for *events* in `state.analytics.events`, every time you call the method `actions.analytics.event()` from any of your React components, the proper tracking info will be sent to Google Tag Manager.

The `actions.analytics.event()` must receive an event object with the following properties.

| Name          | Type   | Required | Description                                                                         |
| ------------- | ------ | -------- | ----------------------------------------------------------------------------------- |
| **`name`**    | string | yes      | The value of this property is mapped to the `event` field of the object sent to GTM |
| **`payload`** | object | yes      | Event payload.                                                                      |

You can add any info you want in the `payload` object.

These values will be transfomed (by this package) into the proper format before sending the data to Google Tag Manager


# @frontity/comscore-analytics

[Comscore](https://www.comscore.com/) Analytics package for Frontity.

## Table of Contents

* [Install](/frontity-packages/features-packages/analytics/comscore-analytics#install)
* [Settings](/frontity-packages/features-packages/analytics/comscore-analytics#settings)
* [Usage](/frontity-packages/features-packages/analytics/comscore-analytics#usage)
  * [`actions.analytics.pageview`](/frontity-packages/features-packages/analytics/comscore-analytics#actions-analytics-pageview)
  * [`actions.analytics.event`](/frontity-packages/features-packages/analytics/comscore-analytics#actions-analytics-event)

## Install

```bash
npm i @frontity/comscore-analytics
```

## Settings

The [namespace](https://docs.frontity.org/learning-frontity/namespaces) for this package is **`comscoreAnalytics`**.

Every Comscore account has a Tracking ID. To connect the package with a specific account (or accounts) set the following properties in the `frontity.settings.js` file:

* `state.comscoreAnalytics.trackingId`: to specify just one *tracking ID*
* `state.comscoreAnalytics.trackingIds`: to specify a list of *tracking ID's*

```javascript
export default {
  packages: [
    {
      name: "@frontity/comscore-analytics",
      state: {
        comscoreAnalytics: {
          trackingId: "34567890",
        },
      },
    },
  ],
};
```

```javascript
export default {
  packages: [
    {
      name: "@frontity/google-tag-manager-analytics",
      state: {
        comscoreAnalytics: {
          trackingIds: ["34567890", "56789012"],
        },
      },
    },
  ],
};
```

## Usage

The `@frontity/comscore-analytics` package can co-exist with any of the other `analytics` packages such as [`@frontity/google-analytics`](/frontity-packages/features-packages/analytics/google-analytics) and [`@frontity/google-tag-manager-analytics`](https://github.com/frontity/api-reference/tree/899877d910081ad463d808f44a7690d6378d0118/docs-api/frontity-packages/features-packages/analytics/gootle-tag-manager-analytics.md). Once these `analytics` packages have been properly installed and configured their actions will be centralized by the `analytics` namespace.

* `actions.analytics.pageview` will take into account settings in `state.analytics.pageviews`
* `actions.analytics.event` will take into account settings in `state.analytics.events`

> Read more about how to use Analytic packages [here](/frontity-packages/features-packages/analytics#how-to-use).

### `actions.analytics.pageview`

If `@frontity/comscore-analytics` is configured [and enabled for *pageviews*](https://api.frontity.org/frontity-packages/features-packages/analytics#actions-analytics-pageview), every time a link changes (or every time `action.router.set(link)` is launched) tracking information for that page will be sent to Google Analytics.

### `actions.analytics.event`

This package doesn't actually track events for Comscore so any call of the method `actions.analytics.event()` will have no effect for this service.


# @frontity/wp-comments

API reference of \`@frontity/wp-comments\` package

Comments package that adds integration for WordPress native comments.

* [Installation](/frontity-packages/features-packages/wp-comments#installation)
* [Settings](/frontity-packages/features-packages/wp-comments#settings)
  * [In WordPress](/frontity-packages/features-packages/wp-comments#in-wordpress)
  * [In Frontity](/frontity-packages/features-packages/wp-comments#in-frontity)
* [Usage](/frontity-packages/features-packages/wp-comments#usage)
  * [Getting comments of a post](/frontity-packages/features-packages/wp-comments#getting-comments-of-a-post)
  * [Sending new comments for a post](/frontity-packages/features-packages/wp-comments#sending-new-comments-for-a-post)
* [API Reference](/frontity-packages/features-packages/wp-comments#api-reference)
  * [Handlers](/frontity-packages/features-packages/wp-comments#handlers)
    * [`@comments/:id`](/frontity-packages/features-packages/wp-comments#commentsid)
  * [State](/frontity-packages/features-packages/wp-comments#state)
    * [`state.comments.forms[postId]`](/frontity-packages/features-packages/wp-comments#state-comments-forms-postid)
    * [`state.comments.forms[postId].fields`](/frontity-packages/features-packages/wp-comments#state-comments-forms-postid-fields)
    * [`state.source.comment[id]`](/frontity-packages/features-packages/wp-comments#state-source-comment-id)
  * [Actions](/frontity-packages/features-packages/wp-comments#actions)
    * [`actions.comments.updateFields()`](/frontity-packages/features-packages/wp-comments#actions-comments-updatefields)
    * [`actions.comments.submit()`](/frontity-packages/features-packages/wp-comments#actions-comments-submit)
* [Demo](/frontity-packages/features-packages/wp-comments#demo)

## Installation

Add the `wp-comments` package to your project:

```bash
npm i @frontity/wp-comments
```

## Settings

### In WordPress

In order to use this package, you will need to add a single line of configuration to your Wordpress installation:

```php
add_filter( 'rest_allow_anonymous_comments', '__return_true' );
```

[This filter](https://developer.wordpress.org/reference/hooks/rest_allow_anonymous_comments/) enables creating comments for anonymous users via the REST API.

You can add this snippet directly in your theme's `functions.php` file or use a [Code Snippets](https://wordpress.org/plugins/code-snippets/) plugin.

### In Frontity

This package doesn't have any configuration. It just needs to be added to the `packages` array in `frontity.settings.js`.

**`frontity.settings.js`**

```javascript
export default {
  packages: ["@frontity/wp-comments"],
};
```

## Usage

### Getting comments of a post

We can use the [`@comments/:id`](/frontity-packages/features-packages/wp-comments#comments-id) handler to fetch all the comments of a specific post (`actions.source.fetch("@comments/60")`).

This data will be populated to the state so then we can do `state.source.get("@comments/60")` to get the ID's of these comments.

```javascript
>> frontity.state.source.get("@comments/60/")
{
  "isFetching": false,
  "isReady": true,
  "link": "@comments/60/",
  "route": "@comments/60/",
  "query": {},
  "page": 1,
  "postId": 60,
  "items": [
    {
      "type": "comment",
      "id": 285
    },
    ...,

    {
      "type": "comment",
      "id": 274,
      "children": [
        {
          "type": "comment",
          "id": 276
        }
      ]
    },
  ...
  ],
  "total": 32,
  "totalPages": 1,
  "type": "comments",
  "isComments": true
}
```

With each ID we can get the details from the state at [`state.source.comment[id]`](/frontity-packages/features-packages/wp-comments#state-source-comment-id)\`.

```javascript
>> frontity.state.source.comment[285]
{
  "id": 285,
  "parent": 0,
  "author": 0,
  "author_name": "mario",
  "author_url": "",
  "date": "2020-07-31T11:30:25",
  "content": {
    "rendered": "<p>Let&#8217;s see it</p>\n"
  },
  "link": "/2016/the-beauties-of-gullfoss/comment-page-5/#comment-285",
  "type": "comment",
  "author_avatar_urls": {...},
  ...
  }
}"
```

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

{% hint style="info" %}
Take a look at this [diagram](https://excalidraw.com/#json=6489116225044480,z_EpwQgSmtB5DyqfPbce_Q) to learn more about this.
{% endhint %}

### Sending new comments for a post

Every post with a comments form (to send comments) will use [`state.comments.forms[postId]`](/frontity-packages/features-packages/wp-comments#state-comments-forms-postid) to store the data of the comment and the submission status.

The data at `state.comments.forms[postId]` can be updated through the action [`actions.comments.updateFields()`](/frontity-packages/features-packages/wp-comments#actions-comments-updatefields).

```javascript
>> frontity.actions.comments.updateFields(60, {
  content: "Hello world!",
  authorName: "Jamie",
  authorEmail: "jamie@gmail.com"
});
>> frontity.state.comments.forms[60].fields
{
  "content": "Hello world!",
  "authorName": "Jamie",
  "authorEmail": "jamie@gmail.com"
}
```

To send new comments you can use the action [`actions.comments.submit()`](/frontity-packages/features-packages/wp-comments#actions-comments-submit) which will send the data available at [`state.comments.forms[postId].fields`](/frontity-packages/features-packages/wp-comments#state-comments-forms-postid-fields).

The submission status will be stored under under [`state.comments.forms[postId]`](/frontity-packages/features-packages/wp-comments#state-comments-forms-postid) and if there are errors they will be available at the properties `errorMessage`, `errorCode` and `errorStatusCode`.

```javascript
>> frontity.state.comments.forms[60]
{
  "fields": {
    "content": "Nice post!",
    "authorName": "Johnny",
    "authorEmail": "johnny@gmail"
  },
  "isSubmitting": false,
  "isSubmitted": false,
  "isError": true,
  "errorMessage": "Invalid parameter(s): author_email",
  "errorCode": "rest_invalid_param",
  "errorStatusCode": 400
}
```

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

{% hint style="info" %}
Take a look at this [diagram](https://excalidraw.com/#json=6174729664724992,A-DM-LUhTX896Q3e_NW5vQ) to learn more about this.
{% endhint %}

## API Reference

### Handlers

#### `@comments/:id`

This [`wp-source`](https://api.frontity.org/frontity-packages/features-packages/wp-source) handler gets all comments published in the specified post (using its ID) and creates a tree structure with comments and their replies in the data object.

For example, to fetch all comments that belong to the post with ID 60 you would do:

```javascript
await actions.source.fetch("@comments/60");
```

This would fetch all comments associated with that post and populate a data object inside the state (`frontity.state.source.data["@comments/60/"]`) with a tree structure of comments and replies, sorted by date (most recent first).

{% hint style="info" %}
Have a look at the section [**Getting comments of a post**](/frontity-packages/features-packages/wp-comments#getting-comments-of-a-post) to learn more
{% endhint %}

To access the fetched comments you could use something similar to this example:

```javascript
const Comments = connect(({ postId, state }) => {
  // Get comments from state.
  const data = state.source.get(`@comments/${postId}`);

  // Utility to render comments and replies recursively.
  const renderComments = (items) =>
    items.map(({ id, children }) => (
      // You should define your own <Comment/> component!
      <Comment key={id}>
        {/* Render replies */}
        {children && renderComments(children)}
      </Comment>
    ));

  // Render comments if data is ready.
  return data.isReady ? renderComments(data.items) : null;
});
```

### State

#### `state.comments.forms[postId]`

The `wp-comments` package stores a map of objects by post ID in `state.comments.forms`. Each of these objects represents one comment form. These objects are intended to be used as the state of React `<form>` components and contain the input values as well as the submission status. They have the following properties:

| Name              | Type                                                                                          | Description                                                                                                     |
| ----------------- | --------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- |
| **`fields`**      | [object](/frontity-packages/features-packages/wp-comments#state-comments-forms-postid-fields) | Form fields with their values.                                                                                  |
| `isSubmitting`    | boolean                                                                                       | The comment hasn't been received by WP yet.                                                                     |
| `isSubmitted`     | boolean                                                                                       | The comment has been received.                                                                                  |
| `isError`         | boolean                                                                                       | The request has failed.                                                                                         |
| `errorMessage`    | string                                                                                        | Failure reason.                                                                                                 |
| `errorCode`       | string                                                                                        | The error code. Those are defined internally in the WordPress REST API. Example: `rest_comment_invalid_post_id` |
| `errorStatusCode` | number                                                                                        | The HTTP status code that might have been received from the WordPress REST API.                                 |

#### `state.comments.forms[postId].fields`

The following map of fields, representing the current field values that have been input in the form rendered in the given post. The content of this property is updated using the [**`updateFields()`**](/frontity-packages/features-packages/wp-comments#actions-comments-updatefields) action described later.

| Name          | Type   | Required | Description                                                    |
| ------------- | ------ | -------- | -------------------------------------------------------------- |
| `content`     | string | yes      | Content of the comment.                                        |
| `authorName`  | string | no       | Author's name.                                                 |
| `author`      | number | no       | The ID of the author.                                          |
| `authorEmail` | string | no       | Author's email.                                                |
| `authorURL`   | string | no       | URL of the author's site.                                      |
| `parent`      | number | no       | ID of the comment to which this one responds. Default Value: 0 |

{% hint style="info" %}
See the section [**Sending new comments for a post**](/frontity-packages/features-packages/wp-comments#sending-new-comments-for-a-post) to learn more.
{% endhint %}

#### `state.source.comment[id]`

This is the portion of the state where the comments are stored after being fetched from the REST API or POSTed through the [`comments.submit()`](/frontity-packages/features-packages/wp-comments#actions-comments-submit) action.

Thanks to the handler [`@comments/:id`](/frontity-packages/features-packages/wp-comments#comments-id) you can get the [ID's of the comments](https://github.com/frontity/frontity/blob/2eb98ae4e6fee1f93ac5af5c834a3add644ba7b0/packages/wp-comments/types.ts#L158) in a specific post.

With this list of ID's you can get the details for each one at `state.source.comment[id]`.

{% hint style="info" %}
See the section [**Getting comments of a post**](/frontity-packages/features-packages/wp-comments#getting-comments-of-a-post) to learn more.
{% endhint %}

*Example*

```javascript
const data = state.source.get(`@comments/${postId}`);

data.items
  .map(({ id }) => {
    // For each ID we can get the details of each comment at state.source.comment[id]
    const authorName = state.source.comment[id].author_name || "Anonymous";
    const content = state.source.comment[id].content.rendered;
    const date = state.source.comment[id].date;
    return { id, authorName, content, date };
  })
  .forEach(console.log);
```

{% hint style="info" %}
Check a fully working example of [this](https://github.com/frontity-demos/frontity-examples/blob/master/wp-comments/packages/mars-theme/src/components/comments/comments-list.js) in [this `wp-comments` demo](https://github.com/frontity-demos/frontity-examples/tree/master/wp-comments).
{% endhint %}

### Actions

#### `actions.comments.updateFields()`

Update the fields of the form specified by `postId`. This action simply updates what is stored in [`state.comments.forms[postId].fields`](/frontity-packages/features-packages/wp-comments#state-comments-forms-postid-fields) with the given values.

If no fields are specified, the form fields are emptied.

These fields will be used by [`actions.comments.submit()`](/frontity-packages/features-packages/wp-comments#actions-comments-submit) when submitting the comment.

**Syntax**

```typescript
(postId: number, comment: object) => Promise;
```

**Arguments**

| Name           | Type   | Required | Description                                                                                                                                                                                                                                       |
| -------------- | ------ | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ***`postId`*** | number | yes      | The ID of the post where the comment will be published.                                                                                                                                                                                           |
| *`comment`*    | object | no       | Object representing the fields of the comment to be updated. The fields of this object are the same than the ones at [`state.comments.forms[postId].fields`](/frontity-packages/features-packages/wp-comments#state-comments-forms-postid-fields) |

```javascript
actions.comments.updateFields(60, {
  content: "Hello world!",
});
```

{% hint style="info" %}
See the section [**Sending new comments for a post**](/frontity-packages/features-packages/wp-comments#sending-new-comments-for-a-post) to learn more.
{% endhint %}

#### `actions.comments.submit()`

This *asynchronous* action publishes a new comment for the post specified by `postId`. It submits the fields stored in the respective form (i.e. `state.comments.forms[postId]`) or the fields passed as a second argument. If fields are passed, those replace the current values stored in [`state.comments.forms[postId].fields`](/frontity-packages/features-packages/wp-comments#state-comments-forms-postid-fields).

After calling this action, you can access `state.comments.forms[postId].isSubmitted` property (described above) to determine the submission status.

Take into account that this action does not validate input. This means requests are made even though some fields are empty or have invalid values. If that is the case, WordPress will return an error message and populate the error status accordingly.

**Syntax**

```typescript
(postId: number, comment: object) => Promise;
```

**Arguments**

| Name           | Type   | Required | Description                                                                                                                                                                                                           |
| -------------- | ------ | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ***`postId`*** | number | yes      | The ID of the post where the comment will be published.                                                                                                                                                               |
| *`comment`*    | object | no       | Object representing the comment. The fields of this object are the same than the ones at [`state.comments.forms[postId].fields`](/frontity-packages/features-packages/wp-comments#state-comments-forms-postid-fields) |

```javascript
// Submit the comment to the post with ID 60
// using the values stored in `state.comments.forms[60].fields`.
await actions.comments.submit(60);

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

{% hint style="info" %}
Take a look at the section [**Sending new comments for a post**](/frontity-packages/features-packages/wp-comments#sending-new-comments-for-a-post) to learn more.
{% endhint %}

## Demo

This short video demonstrates the usage of the `@frontity/wp-comments` package.

{% embed url="<https://www.youtube.com/watch?v=pG1532lStI8&t=7s>" %}

The project used in the video is available [here](https://github.com/frontity-demos/frontity-examples/blob/master/wp-comments/README.md).


# Collections packages

These packages are collections of useful components or hooks that you can use to speed up the development of your Frontity project:

* [`@frontity/components`](/frontity-packages/collections-packages/components)
* [`@frontity/hooks`](/frontity-packages/collections-packages/hooks)


# @frontity/components

API reference of \`@frontity/components\` package

This package is a collection of React components that have proven to be pretty useful for a Frontity project.

## Table of Contents

* [How to use](/frontity-packages/collections-packages/components#how-to-use)
* [Components](/frontity-packages/collections-packages/components#components)
  * [Link](/frontity-packages/collections-packages/components#link)
    * [Props](/frontity-packages/collections-packages/components#props)
    * [Usage](/frontity-packages/collections-packages/components#usage)
    * [Auto Prefetch](/frontity-packages/collections-packages/components#auto-prefetch)
    * [Custom `Link` component](/frontity-packages/collections-packages/components#custom-link-component)
    * [The `link` processor](/frontity-packages/collections-packages/components#the-link-processor)
  * [Image](/frontity-packages/collections-packages/components#image)
  * [Script](/frontity-packages/collections-packages/components#script)
    * [Props](/frontity-packages/collections-packages/components#props-1)
    * [Usage](/frontity-packages/collections-packages/components#usage-1)
  * [Iframe](/frontity-packages/collections-packages/components#iframe)
    * [Props](/frontity-packages/collections-packages/components#props-2)
    * [Usage](/frontity-packages/collections-packages/components#usage-2)
  * [Switch](/frontity-packages/collections-packages/components#switch)

## How to use

In order to use it, you just have to import the component you want to use in your theme from `@frontity/components/` and place it wherever needed. For example, if we want to use the `<Image />`component:

```javascript
import Image from "@frontity/components/image";
```

## Components

### Link

`<Link />` is a React component that you can use in your Frontity project to define links that works with the internal routing system. Under the hood, this component uses the `actions.router.set(link)` method from `@frontity/tiny-router` and creates an `<a/>` tag.

{% hint style="info" %}
This component requires having `state.source.url` properly configured. Have a look at the guide [Setting the URL of the WordPress data source](https://docs.frontity.org/guides/setting-url-wordpress-source-data) to learn more about this.
{% endhint %}

#### Props

| Name           | Type     | Required | Default     | Description                                                                                                                                                                                                 |
| -------------- | -------- | -------- | ----------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `link`         | string   | yes      | ---         | The URL to link to.                                                                                                                                                                                         |
| `target`       | string   | no       | `_self`     | The [target](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#target) of the anchor. Possible values: `_self` or `_blank`.                                                                       |
| `onClick`      | function | no       | `undefined` | The `onClick` handler. Can be used to pass an optional callback that will be invoked on click.                                                                                                              |
| `scroll`       | boolean  | no       | `true`      | Whether the browser should scroll up to the top upon navigating to a new page.                                                                                                                              |
| `prefetch`     | boolean  | no       | `true`      | Whether Frontity should automatically prefetch this link or not. The prefetching mode is controlled through [`state.theme.autoPrefetch`](/frontity-packages/collections-packages/components#auto-prefetch). |
| `aria-current` | string   | no       | `undefined` | [Indicates the element that represents the current item within a container or set of related elements](https://www.w3.org/TR/wai-aria-1.1/#aria-current).                                                   |

All *"unknown"* props passed to the Link are passed down to an anchor `</a>` tag.

#### Usage

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

const MyComponent = () => (
  <Link link={linkUrl} onClick={(e) => console.log(e)}>
    This is a link
  </Link>
);
```

#### Auto Prefetch

This component can help implementing some auto prefetching strategies. The configuration for this is stored in the `state` so final users can modify it in their sites using their `frontity.settings.js` file.

Imagine that `my-awesome-theme` uses this component. Then, people can set the auto prefetch setting like this:

```javascript
const settings = {
  // Other settings...
  packages: [
    {
      name: "my-awesome-theme",
      state: {
        theme: {
          autoPrefetch: "hover",
        },
      },
    },
    // Other packages...
  ],
};
```

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.        |

#### Custom `Link` component

Using this `<Link />` component is optional. You can create your own `<Link />` component with your own logic.

*Example of a custom `<Link />` component implementation*:

```jsx
import React from "react";
import { connect } from "frontity";

const Link = ({
  state,
  actions,
  link,
  className,
  children,
  "aria-current": ariaCurrent,
}) => {
  const onClick = (event) => {
    // Do nothing if it's an external link
    if (link.startsWith("http")) return;

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

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

  return (
    <a
      href={link}
      onClick={onClick}
      className={className}
      aria-current={ariaCurrent}
    >
      {children}
    </a>
  );
};

export default connect(Link);
```

#### The `link` processor

Frontity provides a `link` processor. The `link` processor works with the `<html2react>` component and can automatically detect `<a>` tags in the page/post content and intelligently convert them into `<Link>` components.

If the `href` attribute of the `<a>` tag is either:

* a relative link, or
* an absolute link on the same domain as the WordPress data source

then the processor will convert the the `<a>` tag into a `<Link>` component.

The `<Link>` component created by the processor will be modelled on the `<a>` tag and will have properties consistent with its attributes - e.g. the `link` property of the `<Link>` component will be the same as the `href` attribute of `<a>` tag being replaced. The processor will also convert absolute links on the same domain to be relative links.

If the `href` attribute of the `<a>` tag is an absolute link on a different domain from the WordPress data source, i.e. it is a link to an external site, then that tag will remain as is and will not be replaced or converted.

In order for this to work the `link` processor must be imported into the theme and included in the list of `html2react` processors. This would normally be done in the root level `index.js` of your theme. See the [`@frontity/html2react`](https://github.com/frontity/api-reference/tree/5cb70b185de018562902d073a62bb934053a5445/docs-api/frontity-packages/features-packages/html2react.md) documentation and [this page](https://docs.frontity.org/learning-frontity/libraries#array-of-processors-from-html-2-react) for more info.

```javascript
import link from "@frontity/html2react/processors/link";
```

```javascript
libraries: {
  html2react: {
    processors: [link],
  },
```

{% hint style="info" %}
This `link` processor needs to be added to any theme that wants to uses this Client-side navigation for embedded links in the content.
{% endhint %}

### Image

`<Image />` is a React component that adds `lazy-loading` to the native WordPress images. Combined with [`@html2react/processors`](/frontity-packages/features-packages/html2react#processors) , you can add this functionality and optimize your images pretty easy.

### Script

`<Script />` is a React component that executes scripts tags found in content.

#### Props

| Name   | Type   | Required | Description                             |
| ------ | ------ | -------- | --------------------------------------- |
| `src`  | string | no       | `URL` to an external `JavaScript` file. |
| `code` | string | no       | internal `JavaScript` code              |
| `id`   | string | no       | `ID` for script element                 |

#### Usage

External JavaScript file:

```javascript
import Script from "@frontity/components/script";

const MyComponent = () => (
    <Script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js />
);
```

Internal JavaScript code

```javascript
import Script from "@frontity/components/script";

const MyComponent = () => (
  <Script
    code={`
        const body = document.querySelector('body');

        // Triggers anytime anywhere in the body of the page is clicked
        body.addEventListener('click', e => {
            e.preventDefault();
            console.log('Button Works');
        });
    `}
  />
);
```

### Iframe

`<Iframe />` is a React component that implement lazy-load on iframe components. The approach taken in implementing this component is based off the edge cases in the table below.

| Intersection Observer | Native Lazy | Height > 0 | Output                |
| --------------------- | ----------- | ---------- | --------------------- |
| true                  | true        | true       | Native Lazy Load      |
| true                  | true        | false      | Intersection Observer |
| true                  | false       | true       | Intersection Observer |
| true                  | false       | false      | Intersection Observer |
| false                 | true        | true       | (not possible)        |
| false                 | true        | false      | (not possible)        |
| false                 | false       | true       | Normal Load (eager)   |
| false                 | false       | false      | Normal Load (eager)   |

{% hint style="info" %}
Native Lazy needs a height attribute. For that reason, we use the Intersection Observer when a height is not provided.
{% endhint %}

#### Props

| Name         | Type   | Required | Description                                               |
| ------------ | ------ | -------- | --------------------------------------------------------- |
| `title`      | string | yes      | internal `JavaScript` code                                |
| `src`        | string | no       | `URL` to an external `JavaScript` file.                   |
| `width`      | string | no       | width of the iframe component                             |
| `height`     | string | no       | height of the iframe component                            |
| `className`  | string | no       | class name for the component                              |
| `loading`    | string | no       | `"lazy"` \| `"eager"` \| `"auto"` Default value: `"lazy"` |
| `rootMargin` | string | no       | margin around root element                                |

#### Usage

```javascript
import Iframe from "@frontity/components/iframe";

const MyComponent = () => (
  <Iframe
    src="https://frontity.org"
    title="Frontity"
    height="500"
    width="500"
  />
);
```

### Switch

The `<Switch />` renders the first child component that returns `true` as the value of its `when` prop.

The last child component (which should not have a `when` prop) will be rendered if no other component matches the condition.

You can use it for routing to different components in your theme:

```javascript
import Switch from "@frontity/components/switch";

const Theme = ({ state }) => {
  const data = state.source.get(state.router.link);

  return (
    <Switch>
      <Loading when={data.isFetching} />
      <Home when={data.isHome} />
      <Archive when={data.isArchive} />
      <Post when={data.isPostType} />
      <ErrorPage /> {/* rendered by default */}
    </Switch>
  );
};
```

But also inside any other component. For example, in a `<Header>` component that has a different menu for the home:

```javascript
import Switch from "@frontity/components/switch";

const Header = ({ state }) => {
  const data = state.source.get(state.router.link);

  return (
    <Switch>
      <MenuHome when={data.isHome} />
      <Menu /> // rendered by default
    </Switch>
  );
};
```

This component is an alternative to applying plain JavaScript logic in React:

```javascript
const Theme = ({ state }) => {
  const data = state.source.get(state.router.link);

  return (
    <>
      {(data.isFetching && <Loading />) ||
        (data.isHome && <Home />) ||
        (data.isArchive && <Archive />) ||
        (data.isPostType && <Post />) || <ErrorPage />}
    </>
  );
};
```


# @frontity/hooks

API reference of \`@frontity/hooks\` package

This package is a collection of React hooks that have proven to be pretty useful for a Frontity project.

## Table of Contents

* [Installation](/frontity-packages/collections-packages/hooks#installation)
* [How to use](/frontity-packages/collections-packages/hooks#how-to-use)
* [Hooks](/frontity-packages/collections-packages/hooks#hooks)

## Installation

Add the `@frontity/hooks` package to your project:

```
npm i @frontity/hooks
```

## How to use

In order to use it, you just have to import the hook you want to use in your theme from `@frontity/hooks` and place it wherever needed. For example, if we want to use the `useInView` hook:

```javascript
import useInView from "@frontity/hooks/use-in-view";
```

## Hooks

These are the hooks available from the package `@frontity/hooks`

* [**Intersection Observer Hooks**](/frontity-packages/collections-packages/hooks/intersection-observer-hooks)
  * [`useInView`](/frontity-packages/collections-packages/hooks/intersection-observer-hooks#useinview)
* [**Infinite Scroll Hooks**](/frontity-packages/collections-packages/hooks/infinite-scroll-hooks)
  * [`useInfiniteScroll`](/frontity-packages/collections-packages/hooks/infinite-scroll-hooks#useinfinitescroll)
  * [`useArchiveInfiniteScroll`](/frontity-packages/collections-packages/hooks/infinite-scroll-hooks#usearchiveinfinitescroll)
  * [`usePostTypeInfiniteScroll`](/frontity-packages/collections-packages/hooks/infinite-scroll-hooks#useposttypeinfinitescroll)


# Infinite Scroll Hooks

The recommended hooks to use for a Infinite Scroll behaviour are:

* `useArchiveInfiniteScroll`
* `usePostTypeInfiniteScroll`

There's also another one available for implementing custom infinite scroll hooks (used internally by the previous two hooks):

* `useInfiniteScroll`

{% hint style="danger" %}
`useInfiniteScroll` is not intented to be used directly by theme developers unless they are creating their own infinite scroll logic. Use `useArchiveInfiniteScroll` or `usePostTypeInfiniteScroll` instead.
{% endhint %}

The main idea behind these hooks is that they return a list of `Wrapper` components, one for each entity listed while scrolling, that handle both the route updating and fetching of the next entity.

## Table of Contents

* [`useArchiveInfiniteScroll`](/frontity-packages/collections-packages/hooks/infinite-scroll-hooks#usearchiveinfinitescroll)
  * [Parameters](/frontity-packages/collections-packages/hooks/infinite-scroll-hooks#parameters)
  * [Return value](/frontity-packages/collections-packages/hooks/infinite-scroll-hooks#return-value)
  * [Usage](/frontity-packages/collections-packages/hooks/infinite-scroll-hooks#usage)
* [`usePostTypeInfiniteScroll`](/frontity-packages/collections-packages/hooks/infinite-scroll-hooks#useposttypeinfinitescroll)
  * [Parameters](/frontity-packages/collections-packages/hooks/infinite-scroll-hooks#parameters-1)
  * [Return value](/frontity-packages/collections-packages/hooks/infinite-scroll-hooks#return-value-1)
  * [Usage](/frontity-packages/collections-packages/hooks/infinite-scroll-hooks#usage-1)
* [Demo](/frontity-packages/collections-packages/hooks/infinite-scroll-hooks#demo)
* [`useInfiniteScroll`](/frontity-packages/collections-packages/hooks/infinite-scroll-hooks#useinfinitescroll)
  * [Parameters](/frontity-packages/collections-packages/hooks/infinite-scroll-hooks#parameters-2)
  * [Return value](/frontity-packages/collections-packages/hooks/infinite-scroll-hooks#return-value-2)
  * [Usage](/frontity-packages/collections-packages/hooks/infinite-scroll-hooks#usage-2)

## `useArchiveInfiniteScroll`

This hook implements the logic needed to include infinite scroll in archives (i.e. categories, tags, the posts archive, etc.).

The hook receives options to set a limit of pages shown automatically, to disable it, and also settings for the intersection observers that are passed to the `useInfiniteScroll` hooks used internally.

`useArchiveInfiniteScroll` is designed to be used inside an `Archive` component. That component would render all the archive pages from the `pages` returned by the hook.

In addition to the above, the hook returns a set of boolean values that indicate if the next page is being fetched, if the limit has been reached, or if the next page returned an error, and a function that allows the next page to be fetched manually.

### Parameters

It accepts an optional object with the following props:

| Name                     | Type                                                                                                          | Default                                                                                                 | Required | Description                                                                                                                                                                                                              |
| ------------------------ | ------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **`active`**             | `boolean`                                                                                                     | `true`                                                                                                  | no       | A boolean indicating if this hook should be active or not. It can be useful in situations where users want to share the same component for different types of Archives, but avoid doing infinite scroll in some of them. |
| **`limit`**              | `number`                                                                                                      | [`Infinity`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Infinity) | no       | The number of pages that the hook should load automatically before switching to manual fetching.                                                                                                                         |
| **`fetchInViewOptions`** | [`IntersectionOptions`](/frontity-packages/collections-packages/hooks/intersection-observer-hooks#parameters) | -                                                                                                       | no       | The intersection observer options for fetching.                                                                                                                                                                          |
| **`routeInViewOptions`** | [`IntersectionOptions`](/frontity-packages/collections-packages/hooks/intersection-observer-hooks#parameters) | -                                                                                                       | no       | The intersection observer options for routing.                                                                                                                                                                           |

{% hint style="info" %}
The IntersectionOptions type refers to the type of the the parameters received by the [`useInView` hook](/frontity-packages/collections-packages/hooks/intersection-observer-hooks#useinview).
{% endhint %}

### Return value

An object with the following properties:

| Name             | Type                  | Description                                                                                                                                                                                                                              |
| ---------------- | --------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`pages`**      | `Array` of page props | An array of the existing pages. Users should iterate over this array in their own layout. The content of each element of this array is explained below.                                                                                  |
| **`isFetching`** | `boolean`             | If it's fetching the next page. Useful to add a loader.                                                                                                                                                                                  |
| **`isLimit`**    | `boolean`             | If it has reached the limit of pages and it should switch to manual mode.                                                                                                                                                                |
| **`isError`**    | `boolean`             | If the next page returned an error. Useful to provide functionality (e.g. a button) to enable the user to try again.                                                                                                                     |
| **`fetchNext`**  | `function`            | A function that fetches the next page. Useful when the limit has been reached (`isLimit === true`) and the user pushes a button to get the next page or when there has been an error fetching the last page and the user wants to retry. |

Each element of the `pages` array has the following structure:

| Name          | Type       | Description                                                                                                  |
| ------------- | ---------- | ------------------------------------------------------------------------------------------------------------ |
| **`key`**     | `string`   | A unique key to be used in the iteration.                                                                    |
| **`link`**    | `string`   | The link of this page.                                                                                       |
| **`isLast`**  | `boolean`  | If this page is the last page. Useful to add separators between pages, but avoid adding it for the last one. |
| **`Wrapper`** | `React.FC` | The Wrapper component that should wrap the real `Archive` component.                                         |

### Usage

````javascript
import { connect } from "frontity";
import useArchiveInfiniteScroll from "@frontity/hooks/use-archive-infinite-scroll";
import ArchivePage from "./archive-page";

/**
 * Simple component showing the usage of the `useArchiveInfiniteScroll` hook.
 *
 * @example
 * ```
 * // In the Theme component:
 * <Switch>
 *   {...}
 *   <Archive when={data.isArchive} />
 * </Switch>
 * ```
 */
const Archive = () => {
  // Get the list of pages from the hook.
  const {
    pages,
    isFetching,
    isLimit,
    isError,
    fetchNext,
  } = useArchiveInfiniteScroll({ limit: 3 });

  return (
    <>
      {pages.map(({ Wrapper, key, link, isLast }) => (
        <Wrapper key={key}>
          <ArchivePage link={link} />
          {!isLast && <PageSeparator />}
        </Wrapper>
      ))}

      {isFetching && <div>Loading more...</div>}

      {(isLimit || isError) && (
        <button onClick={fetchNext}>
          {isError ? "Something failed - Retry" : "Load More"}
        </button>
      )}
    </>
  );
};

export default connect(Archive);
````

## `usePostTypeInfiniteScroll`

Hook that implements the logic needed to include infinite scroll in a post type view (i.e. posts, pages, galleries, etc.).

This hook is more complex than the previous one, as it works by getting the post type entities from the specified archive and thus it doesn't fetch the next post but the next page of posts.

It recevies an `archive` and a `fallback` prop ―both links―, to specify the source of the post entities. If none of them is specified, `state.source.postsPage` is used. When the penultimate post of the first page is rendered, the next page of the archive is fetched. A list of the fetched pages is stored in the browser history state along with the list of posts.

The `limit` prop in this case stands for the number of posts being shown, not the number of fetched pages (as in the case of `useArchiveInfiniteScroll`). In the same way, the `fetchNext` shows the next post, and only fetches the next page of posts if needed.

### Parameters

It accepts an optional object with the following props:

| Name                     | Type                                                                                                          | Default                                                                                                 | Required | Description                                                                                                                                                                                                              |
| ------------------------ | ------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **`active`**             | `boolean`                                                                                                     | `true`                                                                                                  | no       | A boolean indicating if this hook should be active or not. It can be useful in situations where users want to share the same component for different types of Archives, but avoid doing infinite scroll in some of them. |
| **`limit`**              | `number`                                                                                                      | [`Infinity`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Infinity) | no       | The number of posts that are rendered until the user interacts (e.g. clicking a button) in order to show the next post.                                                                                                  |
| **`archive`**            | `string`                                                                                                      | -                                                                                                       | no       | The archive that should be used to get the next posts. If none is present, the previous link is used. If the previous link is not an archive, the homepage is used.                                                      |
| **`fallback`**           | `string`                                                                                                      | -                                                                                                       | no       | The archive that should be used if the `archive` option is not present and the previous link is not an archive.                                                                                                          |
| **`fetchInViewOptions`** | [`IntersectionOptions`](/frontity-packages/collections-packages/hooks/intersection-observer-hooks#parameters) | -                                                                                                       | no       | The intersection observer options for fetching.                                                                                                                                                                          |
| **`routeInViewOptions`** | [`IntersectionOptions`](/frontity-packages/collections-packages/hooks/intersection-observer-hooks#parameters) | -                                                                                                       | no       | The intersection observer options for routing.                                                                                                                                                                           |

{% hint style="info" %}
The IntersectionOptions type refers to the type of the the parameters received by the [`useInView` hook](/frontity-packages/collections-packages/hooks/intersection-observer-hooks#useinview).
{% endhint %}

### Return value

The output of these hooks is pretty similar to the previous one's:

| Name             | Type                  | Description                                                                                                                                                                                                                              |
| ---------------- | --------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`posts`**      | `Array` of post props | An array of the existing posts. Users should iterate over this array in their own layout. The content of each element of this array is explained below.                                                                                  |
| **`isFetching`** | `boolean`             | If it's fetching the next post. Useful to add a loader.                                                                                                                                                                                  |
| **`isLimit`**    | `boolean`             | If it has reached the limit of posts and it should switch to manual mode.                                                                                                                                                                |
| **`isError`**    | `boolean`             | If the next post fetched returned an error. Useful to provide functionality (e.g. a button) to enable the user to try again.                                                                                                             |
| **`fetchNext`**  | `function`            | A function that fetches the next post. Useful when the limit has been reached (`isLimit === true`) and the user pushes a button to get the next post or when there has been an error fetching the last post and the user wants to retry. |

Each element of the `posts` array has the following structure:

| Name          | Type       | Description                                                                                                  |
| ------------- | ---------- | ------------------------------------------------------------------------------------------------------------ |
| **`key`**     | `string`   | A unique key to be used in the iteration.                                                                    |
| **`link`**    | `string`   | The link of this page.                                                                                       |
| **`isLast`**  | `boolean`  | If this post is the last post. Useful to add separators between posts, but avoid adding it for the last one. |
| **`Wrapper`** | `React.FC` | The Wrapper component that should wrap the real `Post` component.                                            |

### Usage

````javascript
import { connect } from "frontity";
import usePostTypeInfiniteScroll from "@frontity/hooks/use-post-type-infinite-scroll";
import PostTypeEntity from "./post-type-entity";

/**
 * Simple component showing the usage of the `usePostTypeInfiniteScroll` hook.
 *
 * @example
 * ```
 * // In the Theme component:
 * <Switch>
 *   {...}
 *   <PostType when={data.isPostType} />
 * </Switch>
 * ```
 */
const PostType = () => {
  // Get the list of posts from the hook.
  const {
    posts,
    isFetching,
    isLimit,
    isError,
    fetchNext,
  } = usePostTypeInfiniteScroll({ limit: 5 });

  return (
    <>
      {posts.map(({ Wrapper, key, link, isLast }) => (
        <Wrapper key={key}>
          <PostTypeEntity link={link} />
          {!isLast && <PostSeparator />}
        </Wrapper>
      ))}

      {isFetching && <div>Loading more...</div>}

      {(isLimit || isError) && (
        <button onClick={fetchNext}>
          {isError ? "Something failed - Retry" : "Load More"}
        </button>
      )}
    </>
  );
};

export default connect(PostType);
````

## Demo

This short video demonstrates the usage of the Infinite Scroll Hooks avalable at the `@frontity/hooks` package.

{% embed url="<https://www.youtube.com/watch?v=30E3lG3-onU>" %}

The project used in the video is available [here](https://github.com/frontity-demos/frontity-examples/tree/master/infinite-scroll-hooks).

## `useInfiniteScroll`

{% hint style="danger" %}
`useInfiniteScroll` is not intented to be used directly by theme developers unless they are creating their own infinite scroll logic. Use `useArchiveInfiniteScroll` or `usePostTypeInfiniteScroll` instead.
{% endhint %}

This is the core hook with the basic logic to build an infinite scroll hook.

It basically receives two links, `currentLink` and `nextLink`, and returns two React refs that should be attached to react elements. The hook uses `useInView` internally to track the visibility of those elements and trigger an `actions.router.set` to update the current link or an `actions.source.fetch` to fetch the next entity. You can pass options for these `useInView` hooks as well, using the `fetchInViewOptions` and the `routeInViewOptions` params.

`useInfiniteScroll` also keeps a record of the fetched & ready entities in the browser history state, in order to restore the list when you go back and forward while navigating. That record is accessible from the browser history state under the `infiniteScroll.links` array.

{% hint style="info" %}
Note: the history state is also accessible from the Frontity state, in `state.router.state`.
{% endhint %}

It was designed to be used inside a `Wrapper` component that would wrap the entity pointed by `currentLink`.

### Parameters

It requires an object with the following props:

| Name                     | Type                                                                                                          | Default | Required | Description                                                                 |
| ------------------------ | ------------------------------------------------------------------------------------------------------------- | ------- | -------- | --------------------------------------------------------------------------- |
| **`currentLink`**        | `string`                                                                                                      | -       | yes      | The current link that should be used to start the infinite scroll.          |
| **`nextLink`**           | `string`                                                                                                      | -       | no       | The next link that should be fetched and loaded once the user scrolls down. |
| **`fetchInViewOptions`** | [`IntersectionOptions`](/frontity-packages/collections-packages/hooks/intersection-observer-hooks#parameters) | -       | no       | The intersection observer options for fetching.                             |
| **`routeInViewOptions`** | [`IntersectionOptions`](/frontity-packages/collections-packages/hooks/intersection-observer-hooks#parameters) | -       | no       | The intersection observer options for routing.                              |

{% hint style="info" %}
The IntersectionOptions type refers to the type of the the parameters received by the [`useInView` hook](/frontity-packages/collections-packages/hooks/intersection-observer-hooks#useinview).
{% endhint %}

### Return value

| Name              | Type        | Description                                                                                                                                                                  |
| ----------------- | ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`supported`**   | `boolean`   | Boolean indicating if the Intersection Observer is supported or not by the browser. In the case `supported` is `false`, all the other returned properties will be undefined. |
| **`routeRef`**    | `React.Ref` | The ref that should be attached to the element used to trigger `actions.router.set`.                                                                                         |
| **`fetchRef`**    | `React.Ref` | The ref that should be attached to the element used to trigger `actions.source.fetch`.                                                                                       |
| **`routeInView`** | `boolean`   | Boolean that indicates when the element used to trigger `actions.router.set` is in the screen.                                                                               |
| **`fetchInView`** | `boolean`   | Boolean that indicates when the element used to trigger `actions.source.fetch` is in the screen.                                                                             |

### Usage

{% hint style="info" %}
Note: this is just an example to illustrate how the `useInfiniteScroll` works. For better examples, see the `useArchiveInfiniteScroll` and the `usePostTypeInfiniteScroll` implementation.
{% endhint %}

```javascript
import { useConnect, connect, css } from "frontity";
import useInfiniteScroll from "@frontity/hooks/use-infinite-scroll";
import { isArchive, isError } from "@frontity/source";

export const wrapperGenerator = ({
  link,
  fetchInViewOptions,
  routeInViewOptions,
}) => {
  const Wrapper = ({ children }) => {
    const { state } = useConnect();

    const current = state.source.get(link);
    const next =
      isArchive(current) && current.next
        ? state.source.get(current.next)
        : null;

    const { supported, fetchRef, routeRef } = useInfiniteScroll({
      currentLink: link,
      nextLink: next?.link,
      fetchInViewOptions,
      routeInViewOptions,
    });

    if (!current.isReady || isError(current)) return null;
    if (!supported) return children;

    const container = css`
      position: relative;
    `;

    const fetcher = css`
      position: absolute;
      width: 100%;
      bottom: 0;
    `;

    return (
      <div css={container} ref={routeRef}>
        {children}
        {<div css={fetcher} ref={fetchRef} />}
      </div>
    );
  };

  return connect(Wrapper);
};
```


# Intersection Observer Hooks

These hooks help you track when an element enters or leaves the viewport.

## Table of Contents

* [`useInView`](/frontity-packages/collections-packages/hooks/intersection-observer-hooks#useinview)
  * [Usage](/frontity-packages/collections-packages/hooks/intersection-observer-hooks#usage)
  * [Parameters](/frontity-packages/collections-packages/hooks/intersection-observer-hooks#parameters)
  * [Return value](/frontity-packages/collections-packages/hooks/intersection-observer-hooks#return-value)
  * [Demo](/frontity-packages/collections-packages/hooks/intersection-observer-hooks#demo)

## `useInView`

This hook just wraps the [`react-intersection-observer`](https://github.com/thebuilder/react-intersection-observer) library which uses internally the [`IntersectionObserver`](https://developer.mozilla.org/en-US/docs/Web/API/IntersectionObserver) API. As some old browsers don't support it, `useInView` also returns a `supported` prop indicating if it's supported or not.

### Usage

```javascript
import useInView from "@frontity/hooks/use-in-view";

const MyLazyElement = ({ children }) => {
  // Get the reference and the visibility status.
  const { ref, inView } = useInView({ triggerOnce: true });

  // Pass the reference to the container and render `children` if
  // the container is visible, or a placeholder otherwise.
  return <div ref={ref}>{inView ? children : <MyPlaceholder />}</div>;
};
```

### Parameters

It accepts a single object with the following props:

| Name              | Type                       | Default  | Required | Description                                                                                                                                                    |
| ----------------- | -------------------------- | -------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`root`**        | Element                    | `window` | no       | The Element that is used as the viewport for checking visibility of the target. Defaults to the browser viewport (`window`) if not specified or if null.       |
| **`rootMargin`**  | string                     | `"0px"`  | no       | Margin around the root. Can have values similar to the CSS margin property, e.g. "10px 20px 30px 40px" (top, right, bottom, left).                             |
| **`threshold`**   | number or array of numbers | `0`      | no       | Number between 0 and 1 indicating the percentage that should be visible before triggering. Can also be an array of numbers, to create multiple trigger points. |
| **`triggerOnce`** | boolean                    | `false`  | no       | Only trigger this method once                                                                                                                                  |

### Return value

An object with the following properties:

| Name            | Type            | Description                                                                                                                                        |
| --------------- | --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`ref`**       | React.RefObject | React reference object pointing to the DOM element. It must be passed to the element you want to track.                                            |
| **`inView`**    | boolean         | Boolean indicating if the element is visible. The value is always `true` if *`supported`* is `false`.                                              |
| **`supported`** | boolean         | Boolean indicating if [`IntersectionObserver`](https://developer.mozilla.org/en-US/docs/Web/API/IntersectionObserver) is supported by the browser. |

### Demo

This [example project](https://github.com/frontity-demos/frontity-examples/blob/master/intersection-observer-hooks/README.md) shows how to use the Intersection Observer Hook `useInView` available in the `@frontity/hooks` package or directly implemented in some components available at `@frontity/components`.


# Themes Packages

Themes packages are those packages that contain the React project used to render the final output (in both client-side and server-side).

With Frontity, you can build your own theme from scratch to match all your project's needs, or use a ready-to-use one, which will make your work easier. You can even install a starter theme and keep working on top of it.

Basically it's the same as WordPress, just keep working as you usually do.

## Official themes

These are the official themes available for your Frontity project:

### `Mars Theme`

Mars theme is a starter theme meant for you to learn some of Frontity's basic functionalities and how to use them. We usually recommend it if this is your first time using the framework.

* [Live demo](https://mars.frontity.org/)
* [GitHub repository](https://github.com/frontity/frontity/tree/dev/packages/mars-theme)
* [npm package](https://www.npmjs.com/package/@frontity/mars-theme)

More information about this theme can be found in the [`@frontity/mars-theme`](/frontity-packages/themes-packages/frontity-mars-theme) page. To learn more about how both Frontity and Mars theme work, check out the [Understanding Mars Theme](https://docs.frontity.org/guides/understanding-mars-theme-1) guide.

### `Twenty Twenty Frontity Theme`

The Twenty Twenty default WordPress theme was included in WordPress 5.3 and ported over to Frontity by the software engineer and designer Segun Adebayo.

* [Live demo](https://twentytwenty.frontity.org/)
* [GitHub repository](https://github.com/frontity/frontity/tree/dev/packages/twentytwenty-theme)
* [npm package](https://www.npmjs.com/package/@frontity/twentytwenty-theme)

More information about this theme can be found in the [`@frontity/twentytwenty-theme`](/frontity-packages/themes-packages/frontity-twentytwenty-theme) page.

## Community themes

These are other public themes for Frontity built by the community that you can use as a starting point to build your next website or blog (listed in alphabetical order):

### `AG Tech - Frontity Theme`

Built by Aamodt Group, this starter theme packs support for Gutenberg, dark mode and fetching menus from WordPress. You can take a look at [Aamodt Group's website](https://aamodtgroup.com/) to see it in action.

* [GitHub repository](https://github.com/aamodtgroup/aamodtgroup)
* [npm package](https://www.npmjs.com/package/@aamodtgroup/agtech)

### `AWSM F1 - Frontity Theme`

A starter theme created by the Aswm Innovations team which includes support for the most common Gutenberg blocks and for the [WP Job Openings plugin](https://github.com/awsmin/frontity-wp-job-openings#readme), among other features.

* [Live demo](https://awsm-theme.vercel.app/)
* [GitHub repository](https://github.com/awsmin/f1)
* [npm package](https://www.npmjs.com/package/@awsmin/f1)

### `Copacetic Frontity Theme`

A theme developed by Taylor White and built off the Frontity Chakra Theme. You can see it in action on his [website](https://taylorchasewhite.com/).

* [GitHub repository](https://github.com/taylorchasewhite/tcw-frontity/)
* [npm package](https://www.npmjs.com/package/@taylorwhite/copacetic-frontity-theme)

### `Forgotten Developer - A terminal-like theme for Frontity`

Created by Divaksh Jain, this is a minimalist and lightweight theme for Frontity with a terminal-like design. Visit [Divaksh's blog](https://divaksh.com/) to see it in action.

* [GitHub repository](https://github.com/Divaksh/forgotten-developer)
* [npm package](https://www.npmjs.com/package/forgotten-developer)

### `Fourothree Theme`

Fourothree is a theme package for Frontity based on [403page.com](https://403page.com/) and developed by 403Page Labs. It started its life as Twenty Twenty theme.

* [GitHub repository](https://github.com/403pagelabs/fourothree-theme)
* [npm package](https://www.npmjs.com/package/@fourothreepage/fourothree-theme)

### `Frontity Chakra Theme`

A Frontity theme made with the Chakra UI React Component Library. Built by the creator of Chakra UI Segun Adebayo, the theme is suited for blogs that make a heavy use of images.

* [Live demo](https://frontity-chakra.vercel.app/)
* [GitHub repository](https://github.com/chakra-ui/frontity-chakra-ui-theme)
* [npm package](https://www.npmjs.com/package/frontity-chakra-theme)

### `Frontity Dimension Theme`

This is a fully responsive Frontity theme designed by HTML5 UP and implemented by Matnard. It uses `react-transition-group` to orchestrate the animations.

* [Live demo](https://dimension-matnard.vercel.app/)
* [GitHub repository](https://github.com/Matnard/frontity-dimension-theme)
* [npm package](https://www.npmjs.com/package/@matnard/dimension-theme)

### `Frontity Starter Theme`

A starter theme for Frontity created by Alexandra Spalato. It's styled with Theme UI and comes with built-in search and dark mode, among other features.

* [Live demo](https://frontity-starter-theme.alexadark.vercel.app/)
* [GitHub repository](https://github.com/alexadark/frontity-starter-theme)
* [npm package](https://www.npmjs.com/package/frontity-starter-theme)

### `Twenty Nineteen Frontity Theme`

The popular Twenty Nineteen WordPress theme was ported over to Frontity by Imran Sayed and Smit Patadiya. It primarily suits blogs, but can be adaptable to a wide range of websites.

* [Live demo](https://twentynineteen.frontity.org/)
* [GitHub repository](https://github.com/imranhsayed/frontity-twentynineteen)
* [npm package](https://www.npmjs.com/package/@frontity/twentynineteen-theme)

{% hint style="info" %}
You can find all the available Frontity themes looking for the [`frontity-theme`](https://www.npmjs.com/search?q=keywords:frontity-theme) tag at npmjs.com. In order to make your theme available to the community, we recommend that you follow these [best practices](https://docs.frontity.org/guides/how-to-share-a-frontity-project).
{% endhint %}

If you'd like to see more projects powered by Frontity and WordPress, please visit the [Showcase page](https://frontity.org/showcase/).


# @frontity/twentytwenty-theme

The **Twenty Twenty** default WordPress theme was included in WordPress 5.3 and ported over to Frontity so you can use it in a headless setup as well. You can check out its **code** and structure on this [GitHub repository](https://github.com/frontity/frontity/tree/dev/packages/twentytwenty-theme) and find it on [npm](https://www.npmjs.com/package/@frontity/twentytwenty-theme).

These are some of the key features included in this theme:

**Accessibility Ready**

The theme is accessible and screen-reader friendly. We added the proper landmarks, roles and labels. We also paid attention to trap focus within modals, ensure focus indicator is visible for all interactive elements.

**Custom Colors**

You can give your site or blog a personal touch by changing the background colors, text colors and primary/accent color in the theme settings. You change the color in one place, all visual elements get updated.

**Search**

The theme comes with a built-in search box to make it easy for your readers to look for specific content. Search box is powered by the robust and performant search engine built into WordPress.

**Featured Images**

Show beautiful featured images for your blog posts. Frontity uses the featured image uploaded to WordPress and renders it on every blog post. You can also opt out of this in the theme settings.

**Content Prefetch**

You can prefetch page for any link to provide an almost instant user experience. All you need do is to change your settings to prefetch pages when the user "hovers" on a link, when the link is visible on screen, or prefetch all links on the current page.

**Pagination**

Frontity's theme has the same pagination as the original WordPress theme. This way you can have access to different pages in the footer, and navigate easily between pages.

## Demo

![Homepage view in Twenty Twenty Frontity Theme.](https://frontity.org/wp-content/uploads/2021/04/screenshot-homepage-view-twentytwenty-frontity-theme.png)

You can check out all the features in this [**theme demo**](https://twentytwenty.frontity.org/) or even in the [Frontity blog](https://frontity.org/blog/).

## Settings

In this theme, apart from changing the colors, you can select other options. You can configured it via the `frontity.settings.js` file. The theme options can be specified in the `state.theme` property.

Here you have an example of a possible configuration (each setting is explained later in detail):

```javascript
{
  name: "@frontity/twentytwenty-theme",
  state: {
    theme: {
      menu: [
        ["Home", "/"],
        ["Nature", "/category/nature/"],
        ["Travel", "/category/travel/"],
        ["Japan", "/tag/japan/"],
        ["About Us", "/about-us/"]
      ],
      colors: {
        primary: "#E6324B",
        headerBg: "#ffffff",
        footerBg: "#ffffff",
        bodyBg: "#f5efe0"
      },
      showSearchInHeader: true,
      showAllContentOnArchive: false,
      featuredMedia: {
        showOnArchive: true,
        showOnPost: true
      },
      autoPreFetch: "hover",
      fontSets: "us-ascii"
    }
  }
},
```

All the settings that can be set under `state.theme` and their description:

| Key                         | Description                                                                                                                                                                                                                                | Default value |
| --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------- |
| menu                        | Menu links to display in the header                                                                                                                                                                                                        | \[]           |
| colors.primary              | Used throughout most of the application to style links and other common elements.                                                                                                                                                          | `#cd2653`     |
| colors.headerBg             | Color of the header background.                                                                                                                                                                                                            | `#ffffff`     |
| colors.footerBg             | Color of the footer background.                                                                                                                                                                                                            | `#ffffff`     |
| colors.bodyBg               | Color of the body background.                                                                                                                                                                                                              | `#f5efe0`     |
| showSearchInHeader          | Whether to show the search button in page header                                                                                                                                                                                           | true          |
| showAllContentOnArchive     | Whether to show all post content or only excerpt in archive view                                                                                                                                                                           | false         |
| featuredMedia.showOnArchive | Whether to show featured image on archive view                                                                                                                                                                                             | true          |
| featuredMedia.showOnPost    | Whether to show featured media on post view                                                                                                                                                                                                | true          |
| autoPreFetch                | Whether to auto-fetch links on a page. Possible values: - `no` → don't auto-tech any links - `all` → auto-fetch all the links of the page - `in-view` → auto-fetch just the links that are in-view - `hover` → auto-fetch links when hover | no            |
| fontSets                    | Which font set to use: - `us-ascii` - `latin` - `all`                                                                                                                                                                                      | `all`         |

## API Reference

### Actions

#### actions.theme.openMobileMenu

It changes `state.theme.isMobileMenuOpen` to `true`, so it opens the mobile menu.

#### actions.theme.closeMobileMenu

It changes `state.theme.isMobileMenuOpen` to `false`, so it closes the mobile menu.

#### actions.theme.openSearchModal

It changes `state.theme.isSearchModalOpen` to `true`, so it opens the search bar.

#### actions.theme.closeSearchModal

It changes `state.theme.isSearchModalOpen` to `false`, so it closes the search bar.

### Libraries

This theme doesn't have its own libraries, but it includes the image processor of [@frontity/html2react](/frontity-packages/features-packages/html2react), so all the `<img>` tags are converted into the [`<Image />` component](/frontity-packages/collections-packages/components#image).


# @frontity/mars-theme

Mars theme is meant to be considered a starter theme or a theme to show people how to use some of Frontity functionalities. You can check out its **code** and structure on this [GitHub repository](https://github.com/frontity/frontity/tree/dev/packages/mars-theme) and find it on [npm](https://www.npmjs.com/package/@frontity/mars-theme).

You can also find a detailed guide to learn how both Frontity and `mars-theme` work on "[Understanding Mars Theme](https://docs.frontity.org/guides/understanding-mars-theme-1)".

{% hint style="info" %}
Have a look at this episode of Frontity Talks where we talk about the `mars-theme`: 📺 [Frontity Talks 2020-04 - mars-theme \[27:52\]](https://www.youtube.com/watch?v=e6n1j4gwFjQ\&t=1672s).
{% endhint %}

## Demo

![](https://frontity.org/wp-content/uploads/2021/04/screenshot-mars-theme-demo.png)

You can check out all the features in this [**theme demo**](https://mars.frontity.org/)**.**

## Settings

You can configured it via the `frontity.settings.js` file. The theme options can be specified in the `state.theme` property.

Here you have an example of a possible configuration (each setting is explained later in detail):

```javascript
{
  name: "@frontity/mars-theme",
  state: {
    theme: {
      menu: [
        ["Home", "/"],
        ["Nature", "/category/nature/"],
        ["Travel", "/category/travel/"],
        ["Japan", "/tag/japan/"],
        ["About Us", "/about-us/"]
      ],
      featured: {
        showOnList: true,
        showOnPost: true
      }
    }
  }
},
```

All the settings that can be set under `state.theme` and their description:

| Key                      | Description                                 | Default value |
| ------------------------ | ------------------------------------------- | ------------- |
| menu                     | Menu links to display in the header         | \[]           |
| featuredMedia.showOnList | Whether to show featured image on list view | true          |
| featuredMedia.showOnPost | Whether to show featured media on post view | true          |

## API Reference

### Actions

There are some actions used along the theme that you may need useful:

#### actions.theme.toggleMobileMenu

It changes the status of `state.theme.isMobileMenuOpen` , which lets you open/close the mobile menu.

#### actions.theme.closeMobileMenu

It changes `state.theme.isMobileMenuOpen` to `false`, so it closes the mobile menu.

### Libraries

This theme doesn't have its own libraries, but it includes the image and iframe processor of [@frontity/html2react](/frontity-packages/features-packages/html2react), so all the `<img>` tags are converted into the [`<Image />` component](/frontity-packages/collections-packages/components#image) and the \<iframe> tags into the [`<Iframe />` component](/frontity-packages/collections-packages/components#iframe).


# WordPress Plugins

In order to get the most out of Headless WordPress, it will occasionally be necessary to add functionality to the WordPress backend.

Sometimes a plugin will add needed functionality to WordPress, at other times it will add data or content to the REST API.

This is the current list of available plugins:

{% content-ref url="/pages/-MMvBC2VXZNXB8w-4Aqi" %}
[REST API - Head Tags](/frontity-plugins/rest-api-head-tags)
{% endcontent-ref %}

{% content-ref url="/pages/-MZO3-s-Q4XM2zZ5sFO3" %}
[Frontity Embedded Mode](/frontity-plugins/embedded-mode)
{% endcontent-ref %}


# REST API - Head Tags

This plugin adds all the tags in the `<head>` section of a site to WordPress REST API responses. You can download it [here](https://wordpress.org/plugins/rest-api-head-tags/).

It is perfect if you are using WordPress for a headless set-up and you would like to add the **meta tags** generated by your **WordPress** **SEO plugin** (like Yoast SEO or All-in-One SEO Pack) to the WordPress REST API output.

{% hint style="warning" %}
If you are using Yoast SEO version 14.0 or later, we recommend that you use the [`@frontity/yoast`](/frontity-packages/features-packages/yoast) package instead.
{% endhint %}

## Table of Contents

* [Prerequisites](/frontity-plugins/rest-api-head-tags#prerequisites)
* [Compatibility](/frontity-plugins/rest-api-head-tags#compatibility)
* [How to use this plugin](/frontity-plugins/rest-api-head-tags#how-to-use-this-plugin)
  * [Entities with head tags](/frontity-plugins/rest-api-head-tags#entities-with-head-tags)
  * [In a Frontity project](/frontity-plugins/rest-api-head-tags#in-a-frontity-project)
  * [In a different project](/frontity-plugins/rest-api-head-tags#in-a-different-project)
* [Settings](/frontity-plugins/rest-api-head-tags#settings)
  * [Purge cache](/frontity-plugins/rest-api-head-tags#purge-cache)
  * [Enable output](/frontity-plugins/rest-api-head-tags#enable-output)
  * [Skip cache](/frontity-plugins/rest-api-head-tags#skip-cache)
* [WordPress installation](/frontity-plugins/rest-api-head-tags#wordpress-installation)
* [Troubleshooting](/frontity-plugins/rest-api-head-tags#troubleshooting)

### Prerequisites

This package depends on the [PHP DOM library](https://www.php.net/manual/en/book.dom.php). It looks like not all PHP servers include it by default, so make sure you have it installed before using this plugin.

> If you get some errors regarding this dependency have a look a this [thread](https://github.com/frontity/wp-plugins/issues/35).

### Compatibility

This plugin is compatible and works out of the box with the following WordPress SEO plugins:

* **Yoast SEO**
* **All in One SEO Pack**

Are you using a different SEO plugin and want to know if it's compatible? Feel free to ask in the [community forum](https://community.frontity.org/).

## How to use this plugin

### Entities with head tags

The plugin has been developed to include the `head_tags` field to the REST API response of most of the WordPress core entities:

* Posts, pages, attachments and custom post types
* Post types: for archive pages
* Categories, tags and custom taxonomies
* Authors

### In a Frontity project

In this case, you just have to install the [`@frontity/head-tags`](/frontity-packages/features-packages/head-tags) package and **it'll work automatically**.

### In a different project

You need to understand better how it works and **add the data manually**.

#### How to fetch the head\_tags field manually

You have to get each entity from its respective REST API endpoint.

For example, for fetching the posts you should go to `/wp-json/wp/v2/posts&id=123` endpoint, for fetching the categories you have to go to `wp-json/wp/v2/categories&id=123,` and for custom post types or custom taxonomies would be a different URL in each case.

In the case of the homepage, it could be less intuitive and you should go to `/wp-json/wp/v2/types/post.` As previously said, each entity has a different endpoint so if you aren't familiar with this, you should check the [WordPress REST API reference](https://developer.wordpress.org/rest-api/reference/) for more info.

Inside each endpoint, it will be a new field named `head_tags` , which will be an array of objects representing the tags that WordPress would normally include inside the HTML `head` element. These objects have the properties `tag`, `attributes` and `content`.

For example for these HTML tags:

```
<title>Hello wordl! - My Site</title>
  <meta name="robots" content="max-snippet:-1, max-image-preview:large, max-video-preview:-1">
  <link rel="canonical" href="<http://mysite.com/hello-world/>" />
```

This would be the content of the `head_tags` field:

```
"head_tags": [
  {
    "tag": "title",
    "content": "Hello world! - My Site"
  },
  {
    "tag": "meta",
    "attributes": {
      "name": "robots",
      "content": "max-snippet:-1, max-image-preview:large, max-video-preview:-1"
    }
  },
  {
    "tag": "link",
    "attributes": {
      "rel": "canonical",
      "href": "<http://mysite.com/hello-world/>"
    }
  }
]
```

## Settings

The settings of this plugin are really simple.

### Purge cache

In order to not affect the performance of your web, the `head_tags` field is cached for all your responses, but we've added a button to purge this cache in case something changes.

### Enable output

By default, the `head_tags` field is included in the common endpoint of each entity. You can configure it so it doesn't appear by default and to be shown when you include the `head_tags=true` query.

For example, with the output disabled, `https://mysite.com/wp-json/wp/v2/posts` won't show the `head_tags` field unless you have the query `? head_tags=true` at the end.

### Skip cache

In case you want to skip the cache, you can do so by adding to the query the parameter `skip_cache`.

There are some cache plugins for the REST API that also use the same parameter. In case you want to ignore the cache for the REST API call but not for the head tags, you can use `skip_cache&head_tags_skip_cache=false`.

## WordPress installation

1. First of all you have to [install the plugin](https://wordpress.org/plugins/rest-api-head-tags/). You can do it:
   * **Automatic**: from within the WordPress dashboard go to Plugins, click the `Add New` button, search for `REST API - Head Tags` (by Frontity) and click `Install Now`.
   * **Manual**: this method requires that you download the plugin and upload it to your web server via FTP.

     For a more detailed explanation, WordPress explains how to do this [on this guide](https://wordpress.org/support/article/managing-plugins/#manual-plugin-installation).
2. Once installed, you have to activate it and it will be running!

The `head_tags` field is cached and enabled by default, but you can purge the cache or disable the output as explained in the [Settings](/frontity-plugins/rest-api-head-tags#settings) section above.

## Troubleshooting

#### The REST API returns an HTML response or it shows an error

* This could happen with some plugins and themes that add hooks to the `wp_head` action.

  What the **REST API - Head Tags** plugin does is to call the `wp_head` action for every entity contained in the REST API response and transform the generated HTML code into a JSON object. That means, any hook registered to that action could be causing the problem if it:

  * generates invalid HTML
  * unexpectedly ends the PHP execution
  * throws an exception

  You can check these topics in the community for specific cases that might help you.

  * NewsPaper theme: [REST API - Head Tags Plugin error with NewsPaper theme](https://community.frontity.org/t/rest-api-head-tags-plugin-error-with-newspaper-theme/1593)
  * Password Protected plugin: [REST API - Head Tags Plugin Breaking with Password Protected](https://community.frontity.org/t/rest-api-head-tags-plugin-breaking-with-password-protected/1071)
* Another reason why it could return an error is when you make a request to a custom post type endpoint that is not expected to have the `head_tags` field (like the `menu-items` endpoint).

  The solution is just [disable](/frontity-plugins/rest-api-head-tags#enable-output) the **REST API - Head Tags** plugin output when making those requests, simply adding `head_tags=false` to the query, as explained in [REST API - Head Tags plugin not working with WordPress REST API Menus Endpoints](https://community.frontity.org/t/rest-api-head-tags-plugin-not-working-with-wordpress-rest-api-menus-endpoints/1212).

#### Missing tags inside `head_tags` field

* One possibility is that the WordPress theme or plugin generates those fields in a different action than `wp_head`. This is not easy to solve, you would have to find what hooks add the missing fields and attach them to `wp_head`, or write those hooks yourself.

  A known case for this is the **NewsPaper theme**, wich adds the `<title>` tag in `header.php` directly - without using the `wp_head` action. You can take a look at [REST API - Head Tags Plugin error with NewsPaper theme](https://community.frontity.org/t/rest-api-head-tags-plugin-error-with-newspaper-theme/1593/14) for a specific solution if you are using this theme.
* This problem could also happen if there is no theme at all in your WordPress site, because themes are normally what add those tags inside `<head>`. You can try using one that comes with WordPress by default to fix this.
* Also, if you are using a plugin or any other system to cache the REST API responses you can try also clearing the cache.

#### Unexpected or outdated `head_tags` field

* Try [clearing the cache](/frontity-plugins/rest-api-head-tags#purge-cache).
* Try using [`skip_cache=true`](/frontity-plugins/rest-api-head-tags#skip-cache) as a parameter in a specific REST API request to regenerate the `head_tags` field values that appear in the response.


# Frontity Embedded Mode

This plugin enables the [**Embedded Mode**](https://docs.frontity.org/architecture/embedded-mode) implementation of Frontity in a WordPress installation. You can download it from [here](https://github.com/frontity/frontity-embedded/archive/refs/heads/master.zip).

{% hint style="info" %}
Take a look at the [*Frontity - Embedded Mode* repository](https://github.com/frontity/frontity-embedded) to see the code for this plugin.
{% endhint %}

This *Frontity Embedded Mode* plugin replaces the active WordPress theme with the Frontity installation. Frontity therefore effectively becomes the WordPress sites' theme. It works by substituting it's own [`template.php`](https://github.com/frontity/frontity-embedded/blob/master/includes/template.php) in place of any call made to the [WordPress template hierarchy](https://developer.wordpress.org/themes/basics/template-hierarchy/).

## Table of Contents

* [The Embedded Mode](/frontity-plugins/embedded-mode#the-embedded-mode)
  * [Features of the Embedded Mode](/frontity-plugins/embedded-mode#features-of-the-embedded-mode)
* [Installation](/frontity-plugins/embedded-mode#installation)
* [Settings](/frontity-plugins/embedded-mode#settings)
  * [Set the URL of the Frontity server](/frontity-plugins/embedded-mode#set-the-url-of-the-frontity-server)
    * [Editing the plugin’s settings page](/frontity-plugins/embedded-mode#editing-the-plugins-settings-page)
    * [Adding an environment variable](/frontity-plugins/embedded-mode#adding-an-environment-variable)
    * [Adding a WordPress constant](/frontity-plugins/embedded-mode#adding-a-wordpress-constant)
  * [Set the static assets public path](/frontity-plugins/embedded-mode#set-the-static-assets-public-path)
    * [Frontity in the same WordPress server](/frontity-plugins/embedded-mode#frontity-in-the-same-wordpress-server)
    * [Frontity in an external server](/frontity-plugins/embedded-mode#frontity-in-an-external-server)
    * [Local Development](/frontity-plugins/embedded-mode#local-development)

## The Embedded Mode

In Frontity there are two main modes of implementation: *Decoupled Mode* and *Embedded Mode*

In the [*Decoupled Mode*](https://docs.frontity.org/architecture/decoupled-mode) the primary domain points to the Frontity site, with the WordPress site being on a secondary domain or on a subdomain of the primary domain.

In the [**Embedded Mode**](https://docs.frontity.org/architecture/embedded-mode) the primary domain points to the WordPress site, and the Frontity site can be on another domain - including the default URL provided by a free hosting service such as [Vercel](https://docs.frontity.org/deployment/deploy-using-vercel).

### 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

{% 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 %}

But there are some *things to be taken into account* when using this Embedded Mode:

* Frontity still needs to be hosted on a separate node server/serverless function (albeit on any domain you like including default domains provided by the hosting provider)
* WordPress still needs to go through its [bootstrap process](https://wordpress.tv/2017/06/22/alain-schlesser-demystifying-the-wordpress-bootstrap-process/) on initial page load
* more routing is involved (WordPress makes a call to Frontity which returns the HTML to WordPress) so **a caching plugin is a necessity** rather than simply a nice to have.

## Installation

Installation is a three step process: Download → Install → Activate.

1. **Download** the zip file from [here](https://github.com/frontity/frontity-embedded/archive/refs/heads/master.zip).
2. **Install** the plugin by [uploading it to WordPress](https://wordpress.org/support/article/managing-plugins/#manual-upload-via-wordpress-admin)
3. **Activate** the plugin by locating it in the Plugins list and clicking on 'Activate'.

## Settings

In order to use Frontity in embedded mode with this *Frontity Embedded Mode* plugin you need to:

* [Set the URL of the Frontity server](/frontity-plugins/embedded-mode#set-the-url-of-the-frontity-server).
* [Set the static assets public path of your Frontity deployment](/frontity-plugins/embedded-mode#set-the-static-assets-public-path).

### Set the URL of the Frontity server

This can be configured in a variety of ways:

* [Editing the plugin’s settings page](/frontity-plugins/embedded-mode#editing-the-plugins-settings-page)
* [Adding an environment variable](/frontity-plugins/embedded-mode#adding-an-environment-variable)
* [Adding a WordPress constant](/frontity-plugins/embedded-mode#adding-a-wordpress-constant)

#### Editing the plugin’s settings page

Once the plugin has been activated a new 'Frontity Embedded Mode' option appears under 'Settings'.

![](/files/-MZO30AIifRqVdoThFdS)

Select this and enter the URL of the Frontity server in the input field. (During development this can be `http://localhost:3000`. In production this will be the deployed location of your Frontity site)

![](/files/-MZO30AK3AfErqvY4Au8)

#### Adding an environment variable

It is also possible to use an environment variable instead of changing the URL in the settings.

```bash
> FRONTITY_SERVER=https://myfrontityserver.com
```

> Note that the environment variable, if it exists, takes precedence over the setting configured in the settings page.

#### Adding a WordPress constant

Lastly a PHP constant can be defined. This would usually be done in the `wp-config.php` file.

```php
define( 'FRONTITY_SERVER', 'https://myfrontityserver.com' );
```

> Note that if the PHP constant exists, it takes precedence over both the environment variable and the settings page setting.

### Set the static assets public path

By default Frontity will look for static assets (such as images, fonts, .js or .css files, etc...) in the path `https://<YOUR-DOMAIN>/static`.

However, since in Embedded mode the primary domain is pointing to the WordPress installation, Frontity will not find the static assets at this location.

In addition it's not always possible to host the static assets with the Frontity deployment - for example, if Frontity is deployed to a [serverless function](https://www.pubnub.com/blog/what-is-a-serverless-function/).

Therefore, if required, it's possible to change the directory or URL where your static assets are stored **at build time**. To do this you can use the [`--public-path` option](https://api.frontity.org/frontity-cli/build-commands/build#the-public-path-option) of the `npx frontity build` command.

The URL (or path) of the static assets will differ depending on the scenario in which you're using this Embedded Mode plugin.

#### Frontity in the same WordPress server

If you are using the same server for both WordPress and Frontity, and your Frontity project is at `/wp-content/frontity`, say, then your static folder will be at `https://yourdomain.com/wp-content/frontity/build/static`.

You can change the folder when you run `npx frontity build` thus:

```bash
> npx frontity build --public-path /wp-content/frontity/build/static
```

This ensures that Frontity will source it's assets from this location instead of from the default `https://<YOUR-DOMAIN>/static`.

#### Frontity in an external server

If you've deployed Frontity to an external hosting service, for example Vercel, then you can use the `--public-path` option to point directly to the Vercel URL:

```bash
> npx frontity build --public-path https://myfrontityapp.vercel.app/static
```

#### Local Development

If you want to use the Embedded mode while you are developing in your local environment, you can do so by using the `--public-path` parameter in the `npx frontity dev` command as well:

```bash
> npx frontity dev --public-path http://localhost:3000/static
```

{% hint style="info" %}
Want to know more about this feature? The development of this plugin was discussed in [this forum thread](https://community.frontity.org/t/embedded-mode/1432).
{% endhint %}


