
WordPress Headless + Astro – Recursos de la clase 02

Angela Sofía Osorio
Tiempo de lectura 2 minutes
¿Qué tal amigos? Estos son los apuntes y recursos de la clase número dos del curso de WordPress Headless + Astro. Recuerda que este es un curso exclusivo para miembros del canal con el nivel de Videos VIP.
Recurso 1 – Las Querys para WpGraphQL
https://gist.github.com/SofiDevO/211e021d784def365923216079fc8106
o también puedes copiarlo directamente de aquí:
#post cards 🦝
query getPostCards {
posts {
nodes {
title
slug
featuredImage {
node {
altText
mediaItemUrl
srcSet(size: MEDIUM)
sizes(size: LARGE)
altText
link
sourceUrl(size: LARGE)
}
}
author {
node {
avatar {
url
}
firstName
lastName
name
slug
}
}
date
excerpt
categories {
nodes {
name
slug
parent {
node {
name
slug
id
}
}
id
uri
}
}
isSticky
seo {
metaDesc
}
}
}
comments {
edges {
node {
id
}
}
}
}
#Post Content 🦝
query getPostContent {
posts(first: 500) {
nodes {
slug
date
title
databaseId
id
author {
node {
avatar {
url
}
lastName
name
firstName
description
id
}
}
content(format: RENDERED)
featuredImage {
node {
altText
mediaItemUrl
srcSet(size: LARGE)
sizes(size: LARGE)
altText
link
sourceUrl(size: LARGE)
}
}
tags {
nodes {
name
}
}
categories {
nodes {
name
}
}
commentCount
dateGmt
modified
seo {
cornerstone
readingTime
metaDesc
}
}
}
}
#Main menu elements by name
query GET_MENU_BY_NAME {
menu(id: "menu", idType: NAME) {
menuItems {
nodes {
url
label
parentId
id
}
}
}
}
#Get categories post card by slug
query getPostsByCategory {
categories(where: {slug: "${slug}"}) {
edges {
node {
id
posts {
nodes {
title
slug
featuredImage {
node {
altText
mediaItemUrl
}
}
author {
node {
avatar {
url
}
firstName
lastName
name
slug
}
}
date
excerpt
categories {
nodes {
name
slug
parent {
node {
name
slug
}
}
}
}
}
}
name
}
}
}
}
query geUsers {
users {
nodes {
avatar {
default
url
}
email
description
comments {
nodes {
status
content(format: RENDERED)
uri
}
}
nickname
name
slug
lastName
firstName
databaseId
uri
}
pageInfo {
endCursor
startCursor
}
edges {
node {
email
description
}
}
}
}
GraphQLAhora es momento de configurar nuestro proyecto de Astro. Así que sigue los pasos del video y usa estas bases como referencia:
Ejemplo de tsconfig.json
Con esta configuración evitamos el uso innecesario de ../../../
en nuestras rutas hacia los archivos.
{
"extends": "astro/tsconfigs/strict",
"include": [".astro/types.d.ts", "**/*", "src/**/*"],
"exclude": ["dist"],
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@src/*": ["src/*"],
"@components/*": ["src/components/*"],
"@atoms/*": ["src/components/atoms/*"],
"@molecules/*": ["src/components/molecules/*"],
"@organisms/*": ["src/components/organisms/*"],
"@layouts/*": ["src/layouts/*"],
"@pages/*": ["src/pages/*"],
"@controllers/*": ["src/controllers/*"],
"@utils/*": ["src/utils/*"],
"@services/*": ["src/services/*"],
"@data/*": ["src/data/*"],
"@styles/*": ["src/styles/*"],
"@img/*": ["public/img/*"]
},
}
}
JSONBaseHead.astro
Este es el archivo donde vamos a configurar todas las metaetiquetas de nuestro head
---
// Import the global.css file here so that it is included on
// all pages through the use of the <BaseHead /> component.
import "@styles/global.css"
import { ClientRouter } from 'astro:transitions';
/* import { ViewTransitions } from "astro:transitions"; */
import { SITE_TITLE, SITE_DESCRIPTION } from "@src/const";
interface Props {
title?: string;
description?: string;
image?: string;
}
const canonicalURL = new URL(Astro.url.pathname, Astro.site);
const {
title = SITE_TITLE,
description = SITE_DESCRIPTION,
image = "/img/ubuntu.png",
} = Astro.props;
---
<!-- Global Metadata -->
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<link rel="icon" type="image/png" href="/img/ubuntu.png" />
<meta name=”robots” content=”index, follow”>
<meta name="generator" content={Astro.generator} />
<title>{title}</title>
<!-- Canonical URL -->
<link rel="canonical" href={canonicalURL} />
<!-- Primary Meta Tags -->
<meta name="title" content={title} />
<meta name="description" content={description} />
<!-- Open Graph / Facebook -->
<meta property="og:type" content="website" />
<meta property="og:url" content={Astro.url} />
<meta property="og:title" content={title} />
<meta property="og:description" content={description} />
<meta property="og:image" content={new URL(image, Astro.url)} />
<!-- Twitter -->
<meta property="twitter:card" content="summary_large_image" />
<meta property="twitter:url" content={Astro.url} />
<meta property="twitter:title" content={title} />
<meta property="twitter:description" content={description} />
<meta property="twitter:image" content={new URL(image, Astro.url)} />
<!-- Adsense -->
<meta name="google-adsense-account" content="ca-pub-3828278469742835">
<!-- css librerias/ cdn -->
<!-- Iconify CDN -->
<script src="https://code.iconify.design/iconify-icon/2.0.0/iconify-icon.min.js"
></script>
AstroAcá está la referencia de uso en nuestro Layout:
---
//Layout.astro
import BaseHead from "@components/BaseHead.astro"
const {title, description, image} = Astro.props;
---
<!doctype html>
<html lang="en">
<head>
<BaseHead title={title} description={description} image={image}/>
</head>
<body>
<slot />
</body>
</html>
<style>
html,
body {
margin: 0;
width: 100%;
height: 100%;
}
</style>
AstroAgregando nuestra configuración a wordpress.ts
//src/services/wordpress.ts
const baseURL = import.meta.env.WORDPRESS_URL;
interface WPGraphQLParams {
query: string;
variables?: object;
}
export async function wpquery({ query, variables = {} }: WPGraphQLParams) {
const res = await fetch(baseURL, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
query,
variables,
}),
});
if (!res.ok) {
throw new Error(`HTTP error! status: ${res.status}`);
}
const { data, errors } = await res.json();
if (errors) {
console.error('GraphQL Errors:', errors);
throw new Error('Error en la consulta GraphQL');
}
return data;
}
TypeScriptFormatear Fecha
// src/utils/formatedDate.js
function formatedDate(date, locale = "es-ES"){
const fecha = new Date(date);
return new Intl.DateTimeFormat(locale, {
year: "numeric",
month: "long",
day: "numeric",
}).format(fecha);
}
export default formatedDate;
JavaScript