{"id":350070,"date":"2021-09-09T07:31:18","date_gmt":"2021-09-09T14:31:18","guid":{"rendered":"https:\/\/css-tricks.com\/?p=350070"},"modified":"2021-09-09T07:31:21","modified_gmt":"2021-09-09T14:31:21","slug":"mars-theme-a-deep-look-at-frontitys-headless-wordpress-theme","status":"publish","type":"post","link":"https:\/\/css-tricks.com\/mars-theme-a-deep-look-at-frontitys-headless-wordpress-theme\/","title":{"rendered":"Mars Theme: A Deep Look at Frontity\u2019s Headless WordPress Theme"},"content":{"rendered":"\n
This post was in progress before Automattic acquired Frontity and its entire team<\/a>. According to Frontity’s founders, the framework will be transitioned into a community-led project and leave the project in \u201ca stable, bug-free position\u201d with documentation and features. Like other open-source community projects, Frontity will remain free as it has been, with opportunities to contribute to the project and make it an even better framework for decoupled WordPress. More detail is found in this FAQ page<\/a>.<\/p>\n\n\n\n In my previous article<\/a>, we created a headless WordPress site with Frontity and briefly looked at its file structure. In this companion article, we will go into a deep dive of the Specifically, we will look at the fundamental parts of Frontity\u2019s Mars Theme, including what they call \u201cbuilding blocks\u201d as well as the different components that come with the package. We\u2019ll cover what those components do, how they work, and finally, how styling works with examples.<\/p>\n\n\n\n\n\n\n\n Ready? Let\u2019s go!<\/p>\n\n\n\n Let\u2019s revisit the file structure of the Frontity project we made in the last article<\/a> as that shows us exactly where to find Frontity\u2019s building blocks, the Frontity core, or The Frontity docs provide a little more information on what happens when a Frontity project is started<\/a>:<\/p>\n\n\n\n When starting frontity, all the packages defined in Next up, we\u2019re familiarizing ourselves with how these building blocks, utilities and exports are used in the Mars Theme package<\/a> to create a functioning Frontity project with a headless WordPress endpoint.<\/p>\n\n\n Before discussing styling and customizing let\u2019s briefly familiarize ourselves with the Mars Theme ( The Mars Theme has three important component files: The This Frontity doc<\/a> explains how Frontity extends its theme using extensibility patterns called Slot<\/a> and Fill<\/a>. An example of the This is everything the package pulls in when initializing the The Mars Theme root component exports<\/a> packages that includes<\/a> any of the roots<\/em>, fills<\/em>, state<\/em>, actions<\/em> and libraries<\/em> elements. More detailed information on The Frontity This example is pulled directly from the Mars Theme<\/a>\u2019s What we just looked at are the theme-level components in Frontity\u2019s Mars Theme. You may have noticed that those components import additional components. Let\u2019s look at a specific one of those, the The List component is exported by In this example, Frontity utilizes To display a list of posts in an archive page, we first have to look Frontity In the code example<\/a> above, the Here\u2019s what we have for The Let\u2019s look at the The The In this We just saw how important the There are a few more components worth looking at before we get into Mars Theme styling.<\/p>\n\n\n The following As explained in this tutorial<\/a>, the Earlier, we defined values for menu items in the The Mars Theme provides two additional menu components \u2014 In Frontity, featured media items values are defined in the Now that we’re more familiar with the Mars Theme, as well as its building blocks, components, and functions, we can move into the different approaches that are available for styling the Mars Theme front-end.<\/p>\n\n\n\n As we move along, you may find this Frontity doc<\/a> a good reference for the various styling approaches we cover.<\/p>\n\n\n For those of us coming from WordPress, styling in Frontity looks and feels different than the various approaches for overriding styles in a typical WordPress theme<\/a>.<\/p>\n\n\n\n First off, Frontity provides us with reusable components made with with styled-components<\/a>, and Emotion<\/a>, a CSS library for styling components in JavaScript, right out of the box. Emotion is popular with React and JavaScript developers, but not so much in the WordPress community based on what I\u2019ve seen. CSS-Tricks has covered CSS-in-JS<\/a> in great detail including how it compares with other styling<\/a>, and this video<\/a> provides background information about the library. So, knowing that both styled-components and Emotion are available and ready to use is nice context as we get started.<\/p>\n\n\n\n Frontity\u2019s documentation has great learning resources for styling frontity components<\/a> as well as set-by-step guidance for customizing Frontity theme styles<\/a>.<\/p>\n\n\n\n I am new to the CSS-in-JS world, except for some general reading on it here and there. I was exposed to CSS-in-JS styling in a Gatsby project, but Gatsby provides a bunch of other styling options<\/a> that aren\u2019t readily available in Frontity or the Mars Theme. That said, I feel I was able to get around that lack of experience, and what I learned from my discovery work is how I\u2019m going to frame things.<\/p>\n\n\n\n So, with that, we are going to visit a few styling examples, referencing Frontity\u2019s styling documentation<\/a> as we go in order to familiarize ourselves with even more information.<\/p>\n\n\n As the name suggests, we need a component in order to style it. So, first, let\u2019s create a styled-component using Emotion\u2019s Let\u2019s say we want to style a reusable @frontity\/mars-theme<\/code> package, or Mars Theme, with a step-by-step walkthrough on how to customize it to make our own. Not only is the Mars Theme a great starter, it\u2019s Frontity\u2019s default theme \u2014 sort of like WordPress Twenty Twenty-One or the like. That makes it a perfect starting point for us to get hands-on experience with Frontity and its features.<\/p>\n\n\n\n
Table of contents<\/h2>\n\n\n
\n\n\nFrontity\u2019s building blocks<\/h3>\n\n\n
frontity.settings.js<\/code>, and
package.json<\/code> and
packages\/mars-theme<\/code> folder. We covered these is great detail before but, in particular, the
package.json<\/code> file gives us a lot of information about the project, like the name, description, author, dependencies, etc. Here\u2019s what that file includes:<\/p>\n\n\n\n
frontity<\/code>:<\/strong> this is the main package that includes all the methods used in Frontity app development. It\u2019s also where the CLI lives.<\/li>
@frontity\/core<\/code>:<\/strong> This is the most important package because it takes care of all the bundling, rendering, merging, transpiling, serving, etc. We don\u2019t need to access to it in order to develop a Frontity app. The full list is captured in the Frontity docs<\/a>.<\/li>
@frontity\/wp-source<\/code>:<\/strong> This package<\/a> connects to the WordPress REST API of our site and fetches all the data needed in the Mars Theme.<\/li>
@frontity\/tiny-router<\/code>:<\/strong> This package<\/a> handles
window.history<\/code> and helps us with routing.<\/li>
@frontity\/htmal2react<\/code>:<\/strong> This package<\/a> converts HTML to React, working with processors<\/a> that match HTML portions while replacing them with React components.<\/li><\/ul>\n\n\n\n
@frontity\/package<\/code> (also referred as Frontity\u2019s building block<\/strong>), is composed of useful React component libraries in its @frontity\/components<\/a> package, which exports helpful things like Link<\/a>, Auto Prefetch<\/a>, Image<\/a>, Props<\/a>, Iframe<\/a>, Switch<\/a>, and other functions, objects, etc., that can be directly imported into Frontity project components. A more detailed description of these components\u2014including syntax info use cases\u2014is in this package reference API<\/a>.<\/p>\n\n\n\n
frontity.settings.js<\/code> are imported by
@frontity\/file-settings<\/code> and the settings and exports from each package are merged by
@frontity\/core<\/code> into a single store where you can access the
state<\/code> and
actions<\/code> of the different packages during development using
@frontity\/connect<\/code>, the frontity state manager.<\/p><\/blockquote>\n\n\n\n
Section 1: Digging into the Mars Theme<\/h3>\n\n\n
@frontity\/mars-theme<\/a><\/code>) file structure<\/a> and how it is put together.<\/p>\n\n\n\n
#! frontity\/mars-theme file structure\npackages\/mars-theme\/\n|__ src\/\n |__ index.js\n |__ components\/\n |__ list\/\n |__ index.js\n |__ list-item.js\n |__ list.js\n |__ pagination.js\n |__ featured-media.js\n |__ header.js\n |__ index.js\n |__ link.js\n |__ loading.js\n |__ menu-icon.js\n |__ menu-model.js\n |__ menu.js\n |__ nav.js\n |__ page-error.js\n |__ post.js\n |__ title.js<\/code><\/pre>\n\n\n\n
\/src\/index.js<\/code> file,
src\/list\/index.js<\/code> and
src\/components\/index.js<\/code>. Frontity\u2019s documentation is a great resource for understanding the Mars Theme, with especially great detail on how different Mars Theme components are defined and connected together in a Frontity site<\/a>. Let\u2019s start familiarizing ourselves with the theme\u2019s three most important components:
Root<\/code>,
Theme<\/code> and
List<\/code>.<\/p>\n\n\n
Theme Root component (
\/src\/index.js<\/code>)<\/h4>\n\n\n
src\/index.js<\/code> file, also known as the theme\u2019s Root<\/a>, is one of the most important Mars Theme components. The Root serves as an entry point<\/a> that targets
<div id=\"root\"><\/code> in the site markup to inject the roots of all the installed packages required to run a Frontity project. A Frontity theme exports a root<\/strong> and other required packages in the DOM as shown in the following use case example from the Frontity documentation<\/a>:<\/p>\n\n\n\n
<!-- \/index.HTML (rendered by Frontity) -->\n<html>\n <head>...<\/head>\n <body>\n <div id=\"root\">\n <MyAwesomeTheme \/>\n <ShareModal \/>\n <YetAnotherPackage \/>\n <\/div>\n <\/body>\n<\/html><\/code><\/pre>\n\n\n\n
Root<\/code> component (
\/src\/index.js<\/code>) is taken from its Mars Theme package<\/a> (
@frontity\/mars-theme<\/code>).<\/p>\n\n\n\n
Root<\/code> component:<\/p>\n\n\n\n
\/\/ mars-theme\/src\/components\/index.js\nimport Theme from \".\/components\";\n\/\/ import processor libraries\nimport image from \"@frontity\/html2react\/processors\/image\";\nimport iframe from \"@frontity\/html2react\/processors\/iframe\";\nimport link from \"@frontity\/html2react\/processors\/link\";\n\nconst marsTheme = {\n \/\/ The name of the extension\n name: \"@frontity\/mars-theme\",\n \/\/ The React components that will be rendered\n roots: {\n \/** In Frontity, any package can add React components to the site.\n * We use roots for that, scoped to the `theme` namespace. *\/\n theme: Theme,\n },\n state: {\n \/** State is where the packages store their default settings and other\n * relevant state. It is scoped to the `theme` namespace. *\/\n theme: {\n autoPrefetch: \"in-view\",\n menu: [],\n isMobileMenuOpen: false,\n featured: {\n showOnList: false,\n showOnPost: false,\n },\n },\n },\n\n \/** Actions are functions that modify the state or deal with other parts of\n * Frontity-like libraries. *\/\n actions: {\n theme: {\n toggleMobileMenu: ({ state }) => {\n state.theme.isMobileMenuOpen = !state.theme.isMobileMenuOpen;\n },\n closeMobileMenu: ({ state }) => {\n state.theme.isMobileMenuOpen = false;\n },\n },\n },\n \/** The libraries that the extension needs to create in order to work *\/\n libraries: {\n html2react: {\n \/** Add a processor to `html2react` so it processes the `<img>` tags\n * and internal link inside the content HTML.\n * You can add your own processors too. *\/\n processors: [image, iframe, link],\n },\n },\n};\n\nexport default marsTheme;<\/code><\/pre>\n\n\n\n
Root<\/code> can be found in this Frontity doc<\/a>.<\/p>\n\n\n
Theme component (
\/src\/components\/index.js<\/code>)<\/h4>\n\n\n
Theme<\/code> component<\/a> is its main root level component that is exported by the
Theme<\/code> namespace (lines 12-16, highlighted in the previous example. The
Theme<\/code> component is wrapped with the
@frontity\/connect<\/code> function (line 51, highlighted below) which provides access to its
state<\/code>,
actions<\/code> and
libraries<\/code> props from the
Root<\/code> component instance and allows
Theme<\/code> component to read the
state<\/code>, manipulate through
actions<\/code>, or use code from other features packages in the libraries.<\/p>\n\n\n\n
\/\/ mars-theme\/src\/components\/index.js\nimport React from \"react\"\n\/\/ Modules from @emotion\/core, @emotion\/styled, css, @frontity\/connect, react-helmet\nimport { Global, css, connect, styled, Head } from \"frontity\";\nimport Switch from \"@frontity\/components\/switch\";\nimport Header from \".\/header\";\nimport List from \".\/list\";\nimport Post from \".\/post\";\nimport Loading from \".\/loading\";\nimport Title from \".\/title\";\nimport PageError from \".\/page-error\";\n\n\/** Theme is the root React component of our theme. The one we will export\n * in roots. *\/\nconst Theme = ({ state }) => {\n \/\/ Get information about the current URL.\n const data = state.source.get(state.router.link);\n\n return (\n <>\n {\/* Add some metatags to the <head> of the HTML with react-helmet *\/}\n <Title \/>\n <Head>\n <meta name=\"description\" content={state.frontity.description} \/>\n <html lang=\"en\" \/>\n <\/Head>\n\n {\/* Add some global styles for the whole site, like body or a's. \n Not classes here because we use CSS-in-JS. Only global HTML tags. *\/}\n <Global styles={globalStyles} \/>\n\n {\/* Render Header component. Add the header of the site. *\/}\n <HeadContainer>\n <Header \/>\n <\/HeadContainer>\n\n {\/* Add the main section. It renders a different component depending\n on the type of URL we are in. *\/}\n <Main>\n <Switch>\n <Loading when={data.isFetching} \/>\n <List when={data.isArchive} \/>\n <Post when={data.isPostType} \/>\n <PageError when={data.isError} \/>\n <\/Switch>\n <\/Main>\n <\/>\n );\n};\n\nexport default connect(Theme);\n\n{\/* define Global styles and styled components used Theme component here *\/}\nconst globalStyles = css`\n body {\n margin: 0;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto,\n \"Droid Sans\", \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n }\n a,\n a:visited {\n color: inherit;\n text-decoration: none;\n }\n`;\nconst HeadContainer = styled.div`\n \/\/ ...\n`;\n\nconst Main = styled.div`\n \/\/ ...\n`;<\/code><\/pre>\n\n\n\n
\/src\/components\/index.js<\/code> component, which we imported with
connect<\/code> from frontity (line 4, above). We are using
state.source.get()<\/code> to retrieve
data<\/code> to be rendered from the current path (lines 39-46, highlighted above); for example,
List<\/code>,
Post<\/code> and other components.<\/p>\n\n\n
Section 2: Working with the List component<\/h3>\n\n\n
List<\/code> component<\/a>.<\/p>\n\n\n\n
src\/components\/list\/index.js<\/code> which uses
@loadable\/components<\/code> to split the List component code in such a way that the component only loads when a user clicks a List view; otherwise it won\u2019t render at all, like when a Post view is clicked instead.<\/p>\n\n\n\n
\/\/ src\/components\/list\/index.js\nimport { loadable } from \"frontity\";\n\n\/\/ Codesplit the list component so it's not included if the users\n\/\/ load a post directly.\nexport default loadable(() => import(\".\/list\"));<\/code><\/pre>\n\n\n\n
loadble<\/code><\/a> functions (integrated from Loadable components<\/a>) for code splitting which loads a component asynchronously and separates code into different bundles that are dynamically loaded at run time. Frontity\u2019s core package API reference<\/a> goes into much more detail.<\/p>\n\n\n
Displaying lists of posts<\/h4>\n\n\n
src\/components\/list\/list.js<\/code> component. As the name suggests, the
List<\/code> component renders lists of posts using
state.source.get(link)<\/code> and its
items<\/code> field (lines 22-25, highlighted below).<\/p>\n\n\n\n
\/\/ src\/components\/list\/list.js\nimport { connect, styled, decode } from \"frontity\";\nimport Item from \".\/list-item\";\nimport Pagination from \".\/pagination\";\n\nconst List = ({ state }) => {\n \/\/ Get the data of the current list.\n const data = state.source.get(state.router.link);\n return (\n <Container>\n {\/* If the list is a taxonomy, we render a title. *\/}\n {data.isTaxonomy && (\n <Header>\n {data.taxonomy}: {state.source[data.taxonomy][data.id].name}\n <\/Header>\n )}\n {\/* If the list is an author, we render a title. *\/}\n {data.isAuthor && (\n <Header>Author: {state.source.author[data.id].name}<\/Header>\n )}\n {\/* Iterate over the items of the list. *\/}\n {data.items.map(({ type, id }) => {\n const item = state.source[type][id];\n \/\/ Render one Item component for each one.\n return <Item key={item.id} item={item} \/>;\n })}\n <Pagination \/>\n <\/Container>\n );\n};\nexport default connect(List);<\/code><\/pre>\n\n\n\n
connect<\/code> function is imported by
frontity<\/code> in line 2 and is wrapped around the exported
connect(List)<\/code> component in line 31 (the last line). Two other components,
list-item.js<\/code> and
pagination.js<\/code> are also imported. Let\u2019s look at those next!<\/p>\n\n\n\n
list-item.js<\/code>:<\/p>\n\n\n\n
\/\/ src\/components\/list\/list-item.js\nimport { connect, styled } from \"frontity\";\nimport Link from \"..\/link\";\nimport FeaturedMedia from \"..\/featured-media\";\n\nconst Item = ({ state, item }) => {\n const author = state.source.author[item.author];\n const date = new Date(item.date);\n return (\n <article>\n {\/* Rendering clickable post Title *\/}\n <Link link={item.link}>\n <Title dangerouslySetInnerHTML={{ __html: item.title.rendered }} \/>\n <\/Link>\n <div>\n {\/* If the post has an author, we render a clickable author text. *\/}\n {author && (\n <StyledLink link={author.link}>\n <AuthorName>\n By <b>{author.name}<\/b>\n <\/AuthorName>\n <\/StyledLink>\n )}\n {\/* Rendering post date *\/}\n <PublishDate>\n {\" \"}\n on <b>{date.toDateString()}<\/b>\n <\/PublishDate>\n <\/div>\n {\/* If the want to show featured media in the\n * list of featured posts, we render the media. *\/}\n {state.theme.featured.showOnList && (\n <FeaturedMedia id={item.featured_media} \/>\n )}\n {\/* If the post has an excerpt (short summary text), we render it *\/}\n {item.excerpt && (\n <Excerpt dangerouslySetInnerHTML={{ __html: item.excerpt.rendered }} \/>\n )}\n <\/article>\n );\n};\n\/\/ Connect the Item to gain access to `state` as a prop\nexport default connect(Item);<\/code><\/pre>\n\n\n\n
Item<\/code> component<\/a> renders the preview of a blog post with clickable post title (lines, 12-14, highlighted above), author name (lines 19-21, highlighted above) and published date (lines: 25-28, highlighted above) along with
<FeaturedMedia \/><\/code> which serves as a post\u2019s optional featured image.<\/p>\n\n\n
Paginating a list of posts<\/h4>\n\n\n
Pagination<\/code> component<\/a> that was rendered earlier in the List component by the
src\/components\/list\/pagination\/js<\/code> that follows:<\/p>\n\n\n\n
\/\/ src\/components\/list\/pagination.js\nimport { useEffect } from \"react\";\nimport { connect, styled } from \"frontity\";\nimport Link from \"..\/link\";\n\nconst Pagination = ({ state, actions }) => {\n \/\/ Get the total posts to be displayed based for the current link\n const { next, previous } = state.source.get(state.router.link);\n \/\/ Pre-fetch the the next page if it hasn't been fetched yet.\n useEffect(() => {\n if (next) actions.source.fetch(next);\n }, []);\n return (\n <div>\n {\/* If there's a next page, render this link *\/}\n {next && (\n <Link link={next}>\n <Text>\u2190 Older posts<\/Text>\n <\/Link>\n )}\n {previous && next && \" - \"}\n {\/* If there's a previous page, render this link *\/}\n {previous && (\n <Link link={previous}>\n <Text>Newer posts \u2192<\/Text>\n <\/Link>\n )}\n <\/div>\n );\n};\n\/**\n * Connect Pagination to global context to give it access to\n * `state`, `actions`, `libraries` via props\n *\/\nexport default connect(Pagination);<\/code><\/pre>\n\n\n\n
Pagination<\/code> component is used so that users can paginate between lists of posts \u2014 you know, like navigating forward from Page 1 to Page 2, or backward from Page 2 to Page 1. The
state<\/code>,
actions<\/code>,
libraries<\/code> props are provided by the global context that wraps and exports them with
connect(Pagination)<\/code>.<\/p>\n\n\n
Displaying single posts<\/h4>\n\n\n
Post<\/code> component<\/a> displays both single posts and pages. Indeed, structurally both are the same except, in posts, we usually display meta data (author, date, categories etc). Meta data isn\u2019t usually used in pages.<\/p>\n\n\n\n
Post<\/code> component, conditional statements are rendered only if the
post<\/code> object contains data (i.e.
data.isPost<\/code>) and a featured image is selected in
sate.theme.featured<\/code> in the theme\u2019s root component:<\/p>\n\n\n\n
\/\/ src\/components\/post.js\nimport { useEffect } from \"react\";\nimport { connect, styled } from \"frontity\";\nimport Link from \".\/link\";\nimport List from \".\/list\";\nimport FeaturedMedia from \".\/featured-media\";\n\nconst Post = ({ state, actions, libraries }) => {\n \/\/ Get information about the current URL.\n const data = state.source.get(state.router.link);\n \/\/ Get the data of the post.\n const post = state.source[data.type][data.id];\n \/\/ Get the data of the author.\n const author = state.source.author[post.author];\n \/\/ Get a human readable date.\n const date = new Date(post.date);\n \/\/ Get the html2react component.\n const Html2React = libraries.html2react.Component;\n\n useEffect(() => {\n actions.source.fetch(\"\/\");\n {\/* Preloading the list component which runs only on mount *\/}\n List.preload();\n }, []);\n\n \/\/ Load the post, but only if the data is ready.\n return data.isReady ? (\n <Container>\n <div>\n <Title dangerouslySetInnerHTML={{ __html: post.title.rendered }} \/>\n {\/* Only display author and date on posts *\/}\n {data.isPost && (\n <div>\n {author && (\n <StyledLink link={author.link}>\n <Author>\n By <b>{author.name}<\/b>\n <\/Author>\n <\/StyledLink>\n )}\n <DateWrapper>\n {\" \"}\n on <b>{date.toDateString()}<\/b>\n <\/DateWrapper>\n <\/div>\n )}\n <\/div>\n {\/* Look at the settings to see if we should include the featured image *\/}\n {state.theme.featured.showOnPost && (\n <FeaturedMedia id={post.featured_media} \/>\n )}\n {\/* Render the content using the Html2React component so the HTML is processed\n by the processors we included in the libraries.html2react.processors array. *\/}\n <Content>\n <Html2React html={post.content.rendered} \/>\n <\/Content>\n <\/Container>\n ) : null;\n};\n{\/* Connect Post to global context to gain access to `state` as a prop. *\/} \nexport default connect(Post);<\/code><\/pre>\n\n\n
Section 3: Links, menus, and featured images<\/h3>\n\n\n
List<\/code> component is when it comes to displaying a group of posts. It\u2019s what we might correlate to the markup we generally use when working with the WordPress loop<\/a> for archive pages, latest posts feeds, and other post lists.<\/p>\n\n\n\n
The Link component (
src\/components\/link.js<\/code>)<\/h4>\n\n\n
MarsLink<\/code> component comes from
src\/components\/link.js<\/a><\/code>, which is a wrapper on top of the
{@link Link}<\/code> component. It accepts<\/a> the same props as the
{@link Link}<\/code> component.<\/p>\n\n\n\n
\/\/ src\/components\/link.js\nimport { connect, useConnect } from \"frontity\";\nimport Link from \"@frontity\/components\/link\";\n\nconst MarsLink = ({ children, ...props }) => {\n const { state, actions } = useConnect();\n\n \/** A handler that closes the mobile menu when a link is clicked. *\/\n const onClick = () => {\n if (state.theme.isMobileMenuOpen) {\n actions.theme.closeMobileMenu();\n }\n };\n\n return (\n <Link {...props} onClick={onClick} className={className}>\n {children}\n <\/Link>\n );\n};\n\/\/ Connect the Item to gain access to `state` as a prop\nexport default connect(MarsLink, { injectProps: false });<\/code><\/pre>\n\n\n\n
Link<\/code> component provides a
link<\/code> attribute that takes a target URL as its value. Quoting from the doc:
it outputs an
<a><\/code> element into the resulting HTML, but without forcing a page reload which is what would occur if you simply added an
<a><\/code> element instead of using the
Link<\/code> component.<\/q><\/p>\n\n\n
Frontity menu (
src\/components\/nav.js<\/code>)<\/h4>\n\n\n
frontity.settings.js<\/code> file. In the
Nav<\/code> component (located in
src\/components\/nav\/js<\/a><\/code>) those menu item values are iterated over, match their page
url<\/code>, and display the component inside the
Header<\/code> component.<\/p>\n\n\n\n
\/\/ src\/components\/nav.js\nimport { connect, styled } from \"frontity\";\nimport Link from \".\/link\";\n\nconst Nav = ({ state }) => (\n <NavContainer>\n \/\/ Iterate over the menu exported from state.theme and menu items value set in frontity.setting.js\n {state.theme.menu.map(([name, link]) => {\n \/\/ Check if the link matched the current page url\n const isCurrentPage = state.router.link === link;\n return (\n <NavItem key={name}>\n {\/* If link URL is the current page, add `aria-current` for a11y *\/}\n <Link link={link} aria-current={isCurrentPage ? \"page\" : undefined}>\n {name}\n <\/Link>\n <\/NavItem>\n );\n })}\n <\/NavContainer>\n);\n\/\/ Connect the Item to gain access to `state` as a prop\nexport default connect(Nav);<\/code><\/pre>\n\n\n\n
menu.js<\/code><\/a> and
menu-modal.js<\/code><\/a> \u2014 for mobile device views which, like
nav.js<\/code>, are available from the Mars Theme GitHub repository<\/a>.<\/p>\n\n\n
Featured Image component (
\/src\/components\/featured-media.js<\/code>)<\/h4>\n\n\n
Root<\/code> component \u2018s
theme.state.featured<\/code> line that we discussed earlier. Its full code is available in the
\/src\/components\/featured-media.js<\/code><\/a> component file.<\/p>\n\n\n\n
Section 4: How to style a Frontity project<\/h3>\n\n\n
Using styled-components<\/h4>\n\n\n
styled<\/code><\/a> function.<\/p>\n\n\n\n
<Button \/><\/code> component that\u2019s used throughout our Frontity project. First, we should create a