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:
import { connect, styled, Head, ... } from "frontity";
Use the
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.
styled
creates new React components from HTML tags, or other React components, with styles attached to them. 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
. And keyframes
is used to define and use animations in your CSS.Use
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.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.ConnectedComponent = connect(Component, options?);
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 | |
- The same component as passed in as the first argument but connected to the Frontity state
Page.js
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);
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.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
const { state, actions, libraries } = useConnect();
- The Frontity state (
state
,actions
andlibraries
)
Page.js
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);
Most of the times you'll use
useConnect
in this way: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:
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 }
toconnect
- Use
const { state, actions, libraries } = useConnect();
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
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. 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.// 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;
`;
- A template literal containing CSS code
- A React component with the styles defined
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};
`;
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.const styleObject = css`
background: pink;
`;
- A template literal containing CSS code
- A style object to be passed to a
css
prop or to the<Global>
'sstyles
prop
import { css } from "frontity";
const Component = () => (
<div
css={css`
background: pink;
`}
>
Styling my theme
</div>
);
It's a React component that creates global styles for the whole Frontity site.
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.<Global styles={styleObject} />
import { Global, css } from "frontity";
const Page = () => (
<>
<Global
styles={css`
body {
margin: 0;
font-family: "Roboto";
}
`}
/>
<OtherContent />
</>
);
It's a function used to define and use animations in your CSS.
const animation = keyframes`
from { ... } to { ... };
`;
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>;
It's a function that loads a component asynchronously generating a different bundle for it. Frontity has integrated and configured Loadable Components, in case you want to check its docs.
const HeavyComponent = loadable(importFunction, options);
Name | Object Property | Type | Required | Description |
importFunction | | function | yes | a function that executes a 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 ) |
- A React component
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>{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.children
: the HTML tags you want to appear inside<head>
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>
);
A React hook to ease the creation of
Slot
components.const fills = useFills("Slot Name");
Name | Type | Required | Description |
slotName | string | yes | A string that refers to the name of the Slot. |
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 . |
Import the hook in your React component and use it to create a component:
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);
You need to wrap the component that uses the
useFills
hook with connect()
in order for that component to work.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:
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
This function is safe to use both server and client-side, but you have to import it first.
const fetchResponsePromise = fetch(resource, init);
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 for the complete list of available settings) |
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;
};
const url = new URL(url, base);
This constructor is safe to use both server and client side, but you have to import it first.
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 |
import { URL } from "frontity";
const getApiPathname = ({ state }) => {
const { pathname } = new URL(state.source.api);
return pathname;
};
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.This
error
method throws an error. In development, it adds a message that encourage users to visit the Frontity community if they need help.try {
new URL(api);
} catch (e) {
error("Add the URL of your WordPress REST API in state.source.api.");
}
Syntax
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 . |
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.
...
if (hasInvalidComponent) {
warn("Children of <Switch /> component should be a type of ReactNode");
}
Syntax
warn((message: string));
Arguments
Name | Type | Required | Description |
message | string | yes | The message that describes the warning.. |
An entity decoder that decodes HTML numeric entities and XML named entities. It works both in the server and the client and it's optimized to be both lightweight and performant.
const decodedText = decode(text);
Name | Type | Required | Description |
text | string | yes | HTML to be escaped. |
string
import { decode } from "frontity";
const decodedText = decode("milk & cookies");
console.log(decodedText); // "milk and cookies"
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.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:
//...
const Content = () => {
//...
<Container>
<Slot name="Before Content">
//...
</Container>