Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

1158 Embed ghost blog articles in frontend app #1161

Merged
merged 17 commits into from Nov 23, 2022
Merged

Conversation

kachar
Copy link
Member

@kachar kachar commented Nov 23, 2022

Closes #1158

Motivation and context

Integrates Ghost API and fetches articles and pages using their Content API

Screenshots:

Articles listing

image

Article viewing

image

Pages

image

Additional updates

Testing

Visit the following URLs and be sure to see the articles from the blog:

Visit the following page and be sure that it's able to open:

New environment variables:

  • GHOST_API_URL - URL of the Ghost blog instance without https:// prefix
  • GHOST_CONTENT_KEY - Public content API key to fetch articles

New dependencies:

@kachar kachar requested a review from imilchev November 23, 2022 16:39
Copy link
Contributor

@dimitur2204 dimitur2204 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Amazing changes! The app feels so much more full this way! I think this might give a good boost to SEO too!

Comment on lines +1 to +12
import React from 'react'
import { PostOrPage } from '@tryghost/content-api'
import { Container, Typography, Unstable_Grid2 as Grid2 } from '@mui/material'

import { baseUrl, routes } from 'common/routes'
import Layout from 'components/layout/Layout'
import BackButton from 'components/navigation/BackButton'

import ReadingTime from './ReadingTime'
import DateCreated from './DateCreated'
import FeaturedImage from './FeaturedImage'
import RenderContent from './RenderContent'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice :)

component="div"
variant="body2"
sx={{ fontSize: (theme) => theme.typography.pxToRem(18) }}
dangerouslySetInnerHTML={{ __html: html }}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a sanity check. This is the way to handle the rich text right?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unless we use markdown I think we're stuck with dangerouslySetInnerHTML

This is the default method that Ghost suggests in their articles and tutorials:

https://ghost.org/docs/jamstack/next/#rendering-a-single-post

Comment on lines +7 to +28
export const getStaticProps: GetStaticProps = async ({ params, locale }) => {
if (typeof params?.slug !== 'string') return { notFound: true }

try {
const client = createGhostClient()
const post = await client.posts.read({ slug: params.slug })

if (!post) {
return { notFound: true }
}
return {
props: {
post,
...(await serverSideTranslations(locale ?? 'bg', ['common', 'blog'])),
},
}
} catch (error) {
console.error(error)
Sentry.captureException(error)
return { notFound: true }
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this the way we should do the fetching of other pages. Or should we continue with the dehydrate/hydrate approach. I saw that both are viable approaches from the react-query docs https://tanstack.com/query/v4/docs/guides/ssr#using-nextjs

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we want to have good SEO we need to have one of the following two approaches:

  • SSR hydratation via getStaticProps and getStaticPaths
  • SSR hydratation via getServerSideProps

In order to have the page content downloaded from the server and embedded in the HTML we need to practice the methods above.

For the blog SP is more appropriate as content changes rarely.
For the campaigns SSP seems to be more appropriate since content needs to be up-to-date often.

ARG GHOST_API_URL
ENV GHOST_API_URL="$GHOST_API_URL"
ARG GHOST_CONTENT_KEY
ENV GHOST_CONTENT_KEY="$GHOST_CONTENT_KEY"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why should these be part of the container? We can set them externally

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@imilchev I'm trying to fix the build running in check-pr and release procedure.

In order to do next build we need to have the static content downloaded from the blog instance.

We can hardcode them in the image, but that removes the ability to replace them via ENV variable, which contradicts with the 12factor rules.

Any ideas are welcome

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@imilchev It's gonna be awesome if we don't need that in the Dockerfile. I'll do a test now.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well.. it doesn't pass

Check out https://github.com/podkrepi-bg/frontend/actions/runs/3534858086/jobs/5932216756

I'm reverting it for now

@kachar kachar merged commit 08bab4e into master Nov 23, 2022
@kachar kachar deleted the 1158-embed-blog-articles branch November 23, 2022 19:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Feature] Embed blog articles inside the frontend app
4 participants