Skip to content

Commit

Permalink
Added Tina fields setting the SEO for both docs and blogs (#2433)
Browse files Browse the repository at this point in the history
* added seo for both docs and blogs

* re-adding openGraph stuff

* removing linting ignore decorators

* tina lock file
  • Loading branch information
isaaclombardssw authored and Calinator444 committed Nov 12, 2024
1 parent a0e5664 commit 91c586b
Show file tree
Hide file tree
Showing 9 changed files with 150 additions and 86 deletions.
32 changes: 16 additions & 16 deletions pages/blog/[slug].tsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
import { client } from '../../tina/__generated__/client'

import * as React from 'react'
import styled from 'styled-components'
import { NextSeo } from 'next-seo'
import { GetStaticProps, GetStaticPaths } from 'next'
import { formatDate, isRelevantPost } from '../../utils'
import {
Layout,
Hero,
DocsTextWrapper,
Hero,
Layout,
} from 'components/layout'
import { fileToUrl } from 'utils/urls'
const fg = require('fast-glob')
import { LastEdited, DocsPagination } from 'components/ui'
import { openGraphImage } from 'utils/open-graph-image'
import { WarningCallout } from '../../utils/shortcodes'
import { useTina } from 'tinacms/dist/react'
import { docAndBlogComponents } from 'components/tinaMarkdownComponents/docAndBlogComponents'
import { DocsPagination, LastEdited } from 'components/ui'
import { GetStaticPaths, GetStaticProps } from 'next'
import { NextSeo } from 'next-seo'
import path from 'path'
import * as React from 'react'
import styled from 'styled-components'
import { useTina } from 'tinacms/dist/react'
import {
TinaMarkdown
} from 'tinacms/dist/rich-text'
import { docAndBlogComponents } from 'components/tinaMarkdownComponents/docAndBlogComponents'
import { openGraphImage } from 'utils/open-graph-image'
import { fileToUrl } from 'utils/urls'
import { formatDate, isRelevantPost } from '../../utils'
import { WarningCallout } from '../../utils/shortcodes'
const fg = require('fast-glob')


function BlogTemplate({ file, siteConfig, ...props }) {
Expand Down Expand Up @@ -58,9 +58,9 @@ function BlogTemplate({ file, siteConfig, ...props }) {
return (
<Layout>
<NextSeo
title={frontmatter.title}
title={data.post.seo?.title || frontmatter.title}
titleTemplate={'%s | ' + siteConfig.title + ' Blog'}
description={excerpt}
description={data.post.seo?.description || excerpt}
openGraph={{
title: frontmatter.title,
description: excerpt,
Expand Down
39 changes: 21 additions & 18 deletions pages/docs/[...slug].tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,26 @@
import React, { useEffect } from 'react'
import styled from 'styled-components'
import { NextSeo } from 'next-seo'
import { GetStaticProps, GetStaticPaths } from 'next'
import { Breadcrumbs } from 'components/DocumentationNavigation/Breadcrumbs'
import { DocsLayout, MarkdownContent } from 'components/layout'
import { NavToggle, DocsPagination, LastEdited } from 'components/ui'
import { getDocsNav } from 'utils/docs/getDocProps'
import { openGraphImage } from 'utils/open-graph-image'
import { docAndBlogComponents } from 'components/tinaMarkdownComponents/docAndBlogComponents'
import ToC from 'components/toc/index'
import { DocsPagination, LastEdited, NavToggle } from 'components/ui'
import { GetStaticPaths, GetStaticProps } from 'next'
import { NextSeo } from 'next-seo'
import Error from 'next/error'
import { NotFoundError } from 'utils/error/NotFoundError'
import { useRouter } from 'next/router'
import * as ga from '../../utils/ga'
import { Breadcrumbs } from 'components/DocumentationNavigation/Breadcrumbs'
import { useTocListener } from 'utils/toc_helpers'
import SetupOverview from '../../components/layout/setup-overview'
import { doc } from 'prettier'
import React, { useEffect } from 'react'
import styled from 'styled-components'
import client from 'tina/__generated__/client'
import { useTina } from 'tinacms/dist/react'
import { TinaMarkdown } from 'tinacms/dist/rich-text'
import { docAndBlogComponents } from 'components/tinaMarkdownComponents/docAndBlogComponents';
import getTableOfContents from 'utils/docs/getTableOfContents'
import ToC from 'components/toc/index'
import { getDocsNav } from 'utils/docs/getDocProps'
import { getSeoDescription } from 'utils/docs/getSeoDescription'
import getTableOfContents from 'utils/docs/getTableOfContents'
import { NotFoundError } from 'utils/error/NotFoundError'
import { openGraphImage } from 'utils/open-graph-image'
import { useTocListener } from 'utils/toc_helpers'
import SetupOverview from '../../components/layout/setup-overview'
import * as ga from '../../utils/ga'

export function DocTemplate(props) {
if (props.new.results.data.doc._sys.filename.includes('setup-overview')) {
Expand All @@ -29,6 +30,7 @@ export function DocTemplate(props) {
}

function _DocTemplate(props) {

// fallback workaround
if (props.notFound) {
return <Error statusCode={404} />
Expand All @@ -51,7 +53,8 @@ function _DocTemplate(props) {
title: doc_data.next?.title,
}
const TableOfContents = getTableOfContents(doc_data.body.children)
const description = getSeoDescription(doc_data.body)
const description = doc_data.seo?.description?.trim() || getSeoDescription(doc_data.body);
const title = doc_data.seo?.title || doc_data.title;

const { activeIds, contentRef } = useTocListener(doc_data)

Expand All @@ -74,11 +77,11 @@ function _DocTemplate(props) {
return (
<>
<NextSeo
title={doc_data.title}
title={title}
titleTemplate={'%s | TinaCMS Docs'}
description={description}
openGraph={{
title: doc_data.title,
title: title,
description: description,
images: [openGraphImage(doc_data.title, '| TinaCMS Docs')],
}}
Expand Down
5 changes: 5 additions & 0 deletions tina/collectionsSchema/blogs.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
import { seoInformation } from "./sharedFields/seoInformation";

export const blogsCollection = {
name: 'post',
label: 'Blog Posts',
path: 'content/blog',
format: 'mdx',
fields: [
{...seoInformation,
description: 'Meta Information – if not set, the meta description will be set to a standard default, and title to "Title | Tina Blogs" per the field below'
},
{
type: 'string',
name: 'title',
Expand Down
7 changes: 6 additions & 1 deletion tina/collectionsSchema/docs.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import {RecipeBlock} from "../../components/blocks/Recipe.template";
import { Template } from "tinacms";
import { RecipeBlock } from "../../components/blocks/Recipe.template";
import { seoInformation } from "./sharedFields/seoInformation";

export const docsCollection = {
name: 'doc',
label: 'Docs',
Expand All @@ -14,6 +16,9 @@ export const docsCollection = {
},
},
fields: [
{...seoInformation,
description: 'Meta Information – if not set, the meta description will be set to the body content and title to "Title | TinaCMS Docs" as per the field below'
},
{
name: 'title',
label: 'Title',
Expand Down
87 changes: 37 additions & 50 deletions tina/collectionsSchema/pages.tsx
Original file line number Diff line number Diff line change
@@ -1,29 +1,47 @@
import { heroTemplate } from '../../components/blocks/Hero.template'
import { Template } from 'tinacms'
import { bookingTemplate } from '../../components/blocks/Booking.template'
import { carouselFeatureTemplate } from '../../components/blocks/CarouselFeature.template'
import { columnsTemplate } from '../../components/blocks/Columns.template'
import { compareBoxTemplate } from '../../components/blocks/CompareBox.template'
import { contentTemplate } from '../../components/blocks/Content.template'
import { eventsTemplate } from '../../components/blocks/Events.template'
import { faqTemplate } from '../../components/blocks/FAQ.template'
import { featureGridTemplate } from '../../components/blocks/FeatureGrid.template'
import { featuresTemplate } from '../../components/blocks/Features.template'
import { flyingTemplate } from '../../components/blocks/Flying.template'
import { heroTemplate } from '../../components/blocks/Hero.template'
import { highlightsSectionTemplate } from '../../components/blocks/HighlightsSection.template'
import { logoGridTemplate } from '../../components/blocks/LogoGrid.template'
import { mediaComponentTemplate } from '../../components/blocks/MediaComponent.template'
import { pricingTemplate } from '../../components/blocks/Pricing.template'
import { faqTemplate } from '../../components/blocks/FAQ.template'
import { contentTemplate } from '../../components/blocks/Content.template'
import { columnsTemplate } from '../../components/blocks/Columns.template'
import { quoteTemplate } from '../../components/blocks/Quote.template'
import { recentPostsTemplate } from '../../components/blocks/RecentPosts.template'
import { RecipeBlock } from '../../components/blocks/Recipe.template'
import { roadmapGridTemplate } from '../../components/blocks/RoadmapGrid.template'
import { showcaseTemplate } from '../../components/blocks/Showcase.template'
import { spacerTemplate } from '../../components/blocks/Spacer.template'
import { storyTemplate } from '../../components/blocks/Story.template'
import { featureGridTemplate } from '../../components/blocks/FeatureGrid.template'
import { logoGridTemplate } from '../../components/blocks/LogoGrid.template'
import { roadmapGridTemplate } from '../../components/blocks/RoadmapGrid.template'
import { recentPostsTemplate } from '../../components/blocks/RecentPosts.template'
import { testimonialsTemplate } from '../../components/blocks/Testimonials.template'
import { quoteTemplate } from '../../components/blocks/Quote.template'
import { eventsTemplate } from '../../components/blocks/Events.template'
import { compareBoxTemplate } from '../../components/blocks/CompareBox.template'
import { bookingTemplate } from '../../components/blocks/Booking.template'
import { mediaComponentTemplate } from '../../components/blocks/MediaComponent.template'
import { Template } from 'tinacms'
import { textAndMediaColumnsComponentTemplate } from '../../components/blocks/TextAndMediaColumns.template'
import { tinaBannerTemplate } from '../../components/blocks/TinaBanner.template'
import { highlightsSectionTemplate } from '../../components/blocks/HighlightsSection.template'
import { spacerTemplate } from '../../components/blocks/Spacer.template'
import {carouselFeatureTemplate} from '../../components/blocks/CarouselFeature.template'
import { RecipeBlock } from '../../components/blocks/Recipe.template'
import { seoInformation } from './sharedFields/seoInformation'

const extendedSeoInformation = {
...seoInformation,
fields: [
...seoInformation.fields,
{
type: 'boolean',
label: 'Has Custom Title Suffix?',
name: 'hasCustomSuffix',
ui: {
component: "toggle",
},
description:
"Set to true to remove the appended suffix ' | Tina'.",
},
]
}

export const pagesCollection = {
label: 'Pages',
Expand All @@ -39,38 +57,7 @@ export const pagesCollection = {
},
},
fields: [
{
type: 'object',
name: 'seo',
label: 'SEO Information',
fields: [
{
type: 'string',
label: 'Title',
name: 'title',
description:
"' | Tina' will be appended to the end of the value. If no title is provided, the default title in siteConfig.tsx is used.",
},
{
type: 'boolean',
label: 'Has Custom Title Suffix?',
name: 'hasCustomSuffix',
ui: {
component: "toggle",
},
description:
"Set to true to remove the appended suffix ' | Tina'.",
},
{
type: 'string',
label: ' Description',
name: 'description',
ui: {
component: 'textarea',
},
},
],
},
extendedSeoInformation,
{
label: 'Page Sections',
name: 'blocks',
Expand Down
34 changes: 34 additions & 0 deletions tina/collectionsSchema/sharedFields/seoInformation.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { TextInputWithCount } from "../../customTinaFormFields/textInputWithCount";


export const seoInformation = {
type: "object",
label: "SEO Values",
name: "seo",
fields: [
{
type: "string",
label: "Title",
description: "Recommended limit of 70 characters",
name: "title",
ui: {
validate: (value) => {
if (value && value.length > 70) {
return "Title should be 70 characters or less";
}
},
component: TextInputWithCount(70),
},
},
{
type: "string",
label: "Description",
description: "Recommended limit of 150 characters",
name: "description",
component: "textarea",
ui: {
component: TextInputWithCount(150, true),
},
},
],
};
26 changes: 26 additions & 0 deletions tina/customTinaFormFields/textInputWithCount.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//ripped out from SSW's Website 😳

import React from "react";
import { wrapFieldsWithMeta } from "tinacms";

export const TextInputWithCount = (max: number, isTextArea: boolean = false) =>
wrapFieldsWithMeta(({ input }) => (
<div className="flex flex-col gap-2">
{isTextArea ? (
<textarea
className="focus:shadow-outline block min-h-40 w-full resize-y rounded-md border border-gray-200 px-3 py-2 text-base text-gray-600 shadow-inner focus:border-blue-500 focus:text-gray-900"
{...input}
/>
) : (
<input
className="focus:shadow-outline block w-full rounded-md border border-gray-200 bg-white px-3 py-2 text-base text-gray-600 shadow-inner transition-all duration-150 ease-out placeholder:text-gray-300 focus:border-blue-500 focus:text-gray-900 focus:outline-none"
{...input}
/>
)}
<p
className={input.value.length > max ? "text-red-500": "text-gray-500"}
>
{input.value.length}/{max}
</p>
</div>
));
4 changes: 4 additions & 0 deletions tina/queries/post.gql
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ query getExpandedPostDocument($relativePath: String!) {
date
last_edited
author
seo {
title
description
}
prev {
... on Post {
id
Expand Down
2 changes: 1 addition & 1 deletion tina/tina-lock.json

Large diffs are not rendered by default.

0 comments on commit 91c586b

Please sign in to comment.