strapi mit next.js
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.
 
 

351 lines
9.2 KiB

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
}