You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
352 lines
9.2 KiB
352 lines
9.2 KiB
2 years ago
|
import qs from "qs"
|
||
|
|
||
|
export function getStrapiURL(path) {
|
||
|
return `${
|
||
|
process.env.NEXT_PUBLIC_STRAPI_API_URL || "http://localhost:1337"
|
||
|
}${path}`
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Helper to make GET requests to Strapi API endpoints
|
||
|
* @param {string} path Path of the API route
|
||
|
* @param {Object} urlParamsObject URL params object, will be stringified
|
||
|
* @param {RequestInit} options Options passed to fetch
|
||
|
* @returns Parsed API call response
|
||
|
*/
|
||
|
export async function fetchAPI(path, urlParamsObject = {}, options = {}) {
|
||
|
// Merge default and user options
|
||
|
const mergedOptions = {
|
||
|
headers: {
|
||
|
"Content-Type": "application/json",
|
||
|
},
|
||
|
...options,
|
||
|
}
|
||
|
|
||
|
// Build request URL
|
||
|
const queryString = qs.stringify(urlParamsObject)
|
||
|
const requestUrl = `${getStrapiURL(
|
||
|
`/api${path}${queryString ? `?${queryString}` : ""}`
|
||
|
)}`
|
||
|
|
||
|
// Trigger API call
|
||
|
const response = await fetch(requestUrl, mergedOptions)
|
||
|
|
||
|
// Handle response
|
||
|
if (!response.ok) {
|
||
|
console.error(response.statusText)
|
||
|
throw new Error(`An error occured please try again`)
|
||
|
}
|
||
|
const data = await response.json()
|
||
|
return data
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
*
|
||
|
* @param {Object} options
|
||
|
* @param {string} options.slug The page's slug
|
||
|
* @param {string} options.locale The current locale specified in router.locale
|
||
|
* @param {boolean} options.preview router isPreview value
|
||
|
*/
|
||
|
export async function getPageData({ slug, locale, preview }) {
|
||
|
// Find the pages that match this slug
|
||
|
const gqlEndpoint = getStrapiURL("/graphql")
|
||
|
const pagesRes = await fetch(gqlEndpoint, {
|
||
|
method: "POST",
|
||
|
headers: {
|
||
|
"Content-Type": "application/json",
|
||
|
},
|
||
|
body: JSON.stringify({
|
||
|
query: `
|
||
|
fragment FileParts on UploadFileEntityResponse {
|
||
|
data {
|
||
|
id
|
||
|
attributes {
|
||
|
alternativeText
|
||
|
width
|
||
|
height
|
||
|
mime
|
||
|
url
|
||
|
formats
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
query GetPages(
|
||
|
$slug: String!
|
||
|
$publicationState: PublicationState!
|
||
|
$locale: I18NLocaleCode!
|
||
|
) {
|
||
|
pages(
|
||
|
filters: { slug: { eq: $slug } }
|
||
|
publicationState: $publicationState
|
||
|
locale: $locale
|
||
|
) {
|
||
|
data {
|
||
|
id
|
||
|
attributes {
|
||
|
locale
|
||
|
localizations {
|
||
|
data {
|
||
|
id
|
||
|
attributes {
|
||
|
locale
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
slug
|
||
|
metadata {
|
||
|
metaTitle
|
||
|
metaDescription
|
||
|
shareImage {
|
||
|
...FileParts
|
||
|
}
|
||
|
twitterCardType
|
||
|
twitterUsername
|
||
|
}
|
||
|
contentSections {
|
||
|
__typename
|
||
|
... on ComponentSectionsBottomActions {
|
||
|
id
|
||
|
title
|
||
|
buttons {
|
||
|
id
|
||
|
newTab
|
||
|
text
|
||
|
type
|
||
|
url
|
||
|
}
|
||
|
}
|
||
|
... on ComponentSectionsHero {
|
||
|
id
|
||
|
buttons {
|
||
|
id
|
||
|
newTab
|
||
|
text
|
||
|
type
|
||
|
url
|
||
|
}
|
||
|
title
|
||
|
description
|
||
|
label
|
||
|
picture {
|
||
|
...FileParts
|
||
|
}
|
||
|
}
|
||
|
... on ComponentSectionsFeatureColumnsGroup {
|
||
|
id
|
||
|
features {
|
||
|
id
|
||
|
description
|
||
|
icon {
|
||
|
...FileParts
|
||
|
}
|
||
|
title
|
||
|
}
|
||
|
}
|
||
|
... on ComponentSectionsFeatureRowsGroup {
|
||
|
id
|
||
|
features {
|
||
|
id
|
||
|
description
|
||
|
link {
|
||
|
id
|
||
|
newTab
|
||
|
text
|
||
|
url
|
||
|
}
|
||
|
media {
|
||
|
...FileParts
|
||
|
}
|
||
|
title
|
||
|
}
|
||
|
}
|
||
|
... on ComponentSectionsTestimonialsGroup {
|
||
|
id
|
||
|
description
|
||
|
link {
|
||
|
id
|
||
|
newTab
|
||
|
text
|
||
|
url
|
||
|
}
|
||
|
logos {
|
||
|
id
|
||
|
title
|
||
|
logo {
|
||
|
...FileParts
|
||
|
}
|
||
|
}
|
||
|
testimonials {
|
||
|
id
|
||
|
logo {
|
||
|
...FileParts
|
||
|
}
|
||
|
picture {
|
||
|
...FileParts
|
||
|
}
|
||
|
text
|
||
|
authorName
|
||
|
authorTitle
|
||
|
link
|
||
|
}
|
||
|
title
|
||
|
}
|
||
|
... on ComponentSectionsLargeVideo {
|
||
|
id
|
||
|
description
|
||
|
title
|
||
|
poster {
|
||
|
...FileParts
|
||
|
}
|
||
|
video {
|
||
|
...FileParts
|
||
|
}
|
||
|
}
|
||
|
... on ComponentSectionsRichText {
|
||
|
id
|
||
|
content
|
||
|
}
|
||
|
... on ComponentSectionsPricing {
|
||
|
id
|
||
|
title
|
||
|
plans {
|
||
|
description
|
||
|
features {
|
||
|
id
|
||
|
name
|
||
|
}
|
||
|
id
|
||
|
isRecommended
|
||
|
name
|
||
|
price
|
||
|
pricePeriod
|
||
|
}
|
||
|
}
|
||
|
... on ComponentSectionsLeadForm {
|
||
|
id
|
||
|
emailPlaceholder
|
||
|
location
|
||
|
submitButton {
|
||
|
id
|
||
|
text
|
||
|
type
|
||
|
}
|
||
|
title
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
`,
|
||
|
variables: {
|
||
|
slug,
|
||
|
publicationState: preview ? "PREVIEW" : "LIVE",
|
||
|
locale,
|
||
|
},
|
||
|
}),
|
||
|
})
|
||
|
|
||
|
const pagesData = await pagesRes.json()
|
||
|
// Make sure we found something, otherwise return null
|
||
|
if (pagesData.data?.pages == null || pagesData.data.pages.length === 0) {
|
||
|
return null
|
||
|
}
|
||
|
|
||
|
// Return the first item since there should only be one result per slug
|
||
|
return pagesData.data.pages.data[0]
|
||
|
}
|
||
|
|
||
|
// Get site data from Strapi (metadata, navbar, footer...)
|
||
|
export async function getGlobalData(locale) {
|
||
|
const gqlEndpoint = getStrapiURL("/graphql")
|
||
|
const globalRes = await fetch(gqlEndpoint, {
|
||
|
method: "POST",
|
||
|
headers: {
|
||
|
"Content-Type": "application/json",
|
||
|
},
|
||
|
body: JSON.stringify({
|
||
|
query: `
|
||
|
fragment FileParts on UploadFileEntityResponse {
|
||
|
data {
|
||
|
id
|
||
|
attributes {
|
||
|
alternativeText
|
||
|
width
|
||
|
height
|
||
|
mime
|
||
|
url
|
||
|
formats
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
query GetGlobal($locale: I18NLocaleCode!) {
|
||
|
global(locale: $locale) {
|
||
|
data {
|
||
|
id
|
||
|
attributes {
|
||
|
favicon {
|
||
|
...FileParts
|
||
|
}
|
||
|
metadata {
|
||
|
metaTitle
|
||
|
metaDescription
|
||
|
shareImage {
|
||
|
...FileParts
|
||
|
}
|
||
|
twitterCardType
|
||
|
twitterUsername
|
||
|
}
|
||
|
metaTitleSuffix
|
||
|
notificationBanner {
|
||
|
type
|
||
|
text
|
||
|
}
|
||
|
navbar {
|
||
|
logo {
|
||
|
...FileParts
|
||
|
}
|
||
|
links {
|
||
|
id
|
||
|
url
|
||
|
newTab
|
||
|
text
|
||
|
}
|
||
|
button {
|
||
|
id
|
||
|
url
|
||
|
newTab
|
||
|
text
|
||
|
type
|
||
|
}
|
||
|
}
|
||
|
footer {
|
||
|
logo {
|
||
|
...FileParts
|
||
|
}
|
||
|
smallText
|
||
|
columns {
|
||
|
id
|
||
|
title
|
||
|
links {
|
||
|
id
|
||
|
url
|
||
|
newTab
|
||
|
text
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
`,
|
||
|
variables: {
|
||
|
locale,
|
||
|
},
|
||
|
}),
|
||
|
})
|
||
|
|
||
|
const global = await globalRes.json()
|
||
|
return global.data.global
|
||
|
}
|