La configuración de blog en solitario definitiva y gratuita con Ghost y Gatsby

 

 

 

  • Listas de verificación de diseño de interfaz inteligente
  • Patrones de diseño de interfaces inteligentes, vídeo de 10h + formación UX

  • Índice
    1. Configurando Fantasma y Gatsby
    2. Tratar con imágenes
    3. Manejo de enlaces internos
    4. Agregar plantillas y estilos
    5. Contenido de página dinámica
    6. Últimos retoques

    Cuando se trata de herramientas para publicar un blog, puede parecer que nunca existe una solución perfecta que combine la personalización con una administración sencilla. En este artículo, veremos paso a paso cómo puede obtener lo mejor de ambos mundos utilizando Ghost como CMS sin cabeza para un sitio estático de Gatsby. Cubriremos todas las partes difíciles en profundidad y le mostraremos que puede hacer todo de forma gratuita.

     

    Hoy en día parece que existe un sinfín de herramientas y plataformas para crear tu propio blog. Sin embargo, muchas de las opciones que existen se inclinan hacia usuarios no técnicos y abstraen todas las opciones de personalización y realmente hacen algo suyo.

    Si usted es alguien que conoce el desarrollo front-end, puede resultar frustrante encontrar una solución que le brinde el control que desea y, al mismo tiempo, elimine al administrador de la gestión del contenido de su blog.

    Ingrese al sistema de gestión de contenido (CMS) sin cabeza. Con un CMS Headless, puedes obtener todas las herramientas para crear y organizar tu contenido, mientras mantienes el 100% de control de cómo se entrega a tus lectores. En otras palabras, obtienes toda la estructura de backend de un CMS sin estar limitado a sus rígidos temas y plantillas de front-end.

    Cuando se trata de sistemas Headless CMS, soy un gran admirador de Ghost. Ghost es de código abierto y fácil de usar, con muchas API excelentes que lo hacen flexible para usar con creadores de sitios estáticos como Gatsby.

    En este artículo, te mostraré cómo puedes usar Ghost y Gatsby juntos para obtener la configuración de blog personal definitiva que te permita mantener el control total de tu entrega frontal, pero deja toda la aburrida gestión del contenido a Ghost.

    Ah, y su configuración y ejecución es 100 % gratuita. Esto se debe a que ejecutaremos nuestra instancia de Ghost localmente y luego la implementaremos en Netlify, aprovechando su generoso nivel gratuito.

    ¡Vamos a sumergirnos!

    Configurando Fantasma y Gatsby

    Ya escribí una publicación inicial sobre esto que cubre los conceptos básicos, por lo que no los profundizaré aquí. En lugar de ello, me centraré en los problemas más avanzados y en los errores que surgen al ejecutar un blog sin cabeza.

     

    Pero en resumen, esto es lo que debemos hacer para tener una configuración básica en funcionamiento desde la cual podamos trabajar:

    • Instale una versión local del Gatsby Starter Blog
    • Instalar fantasma localmente
    • Cambie los datos de origen de Markdown a Ghost (cambie gatsby-source-fileel sistema por gatsby-source-ghost)
    • Modifique las consultas GraphQL en sus gatsby-nodeplantillas y páginas para que coincidan con el gatsby-source-ghostesquema

    Para obtener más detalles sobre cualquiera de estos pasos, puedes consultar mi artículo anterior .

    O simplemente puede comenzar desde el código de este repositorio de Github .

    Tratar con imágenes

    Una vez aclarados los conceptos básicos, el primer problema con el que nos topamos con un blog sin cabeza que se crea localmente es qué hacer con las imágenes.

    Ghost sirve de forma predeterminada imágenes de su propio servidor. Entonces, cuando te quedas sin cabeza con un sitio estático, te encontrarás con una situación en la que tu contenido se crea y se entrega desde un proveedor de borde como Netlify, pero tus imágenes aún están siendo entregadas por tu servidor Ghost.

    Esto no es ideal desde una perspectiva de rendimiento y hace imposible construir e implementar su sitio localmente (lo que significa que tendría que pagar tarifas mensuales por una gota de Digital Ocean, una instancia AWS EC2 o algún otro servidor para alojar su instancia Ghost). ).

    Pero podemos solucionarlo si encontramos otra solución para alojar nuestras imágenes y, afortunadamente, Ghost tiene convertidores de almacenamiento que le permiten almacenar imágenes en la nube.

    Para nuestros propósitos, vamos a utilizar un convertidor AWS S3 , que nos permite alojar nuestras imágenes en AWS S3 junto con Cloudfront para brindarnos un rendimiento similar al resto de nuestro contenido.

    Hay dos opciones de código abierto disponibles: ghost-storage-adapter-s3 y ghost-s3-compat . Lo uso ghost-storage-adapter-s3porque encuentro que los documentos son más fáciles de seguir y se actualizaron más recientemente.

    Dicho esto, si seguí los documentos exactamente, obtuve algunos errores de AWS, así que este es el proceso que seguí y que funcionó para mí:

    • Cree un nuevo depósito S3 en AWS y seleccione Deshabilitar alojamiento estático
    • A continuación, cree una nueva distribución de Cloudfront y seleccione el depósito S3 como origen.
    • Al configurar Cloudfront Distribution, en S3 Bucket Access:

      • Seleccione "Sí, usar OAI (el depósito puede restringir el acceso solo a Cloudfront)".
      • Crear una nueva OAI
      • Y finalmente, seleccione "Sí, actualizar la política del depósito"

      Configuración de la distribución Cloudfront. ( Vista previa grande )

      Esto crea un depósito AWS S3 al que solo se puede acceder a través de la distribución Cloudfront que ha creado.

    Luego, sólo necesita crear un usuario de IAM para Ghost que le permitirá escribir nuevas imágenes en su nuevo S3 Bucket. Para hacer esto, cree un nuevo usuario de IAM programático y adjunte esta política:

    { "Version": "2012-10-17", "Statement": [ { "Sid": "VisualEditor0", "Effect": "Allow", "Action": "s3:ListBucket", "Resource": "arn:aws:s3:::YOUR-S3-BUCKET-NAME" }, { "Sid": "VisualEditor1", "Effect": "Allow", "Action": [ "s3:PutObject", "s3:GetObject", "s3:PutObjectVersionAcl", "s3:DeleteObject", "s3:PutObjectAcl" ], "Resource": "arn:aws:s3:::YOUR-S3-BUCKET-NAME/*" } ]} 

    Con eso, nuestra configuración de AWS está completa, solo necesitamos decirle a Ghost que lea y escriba nuestras imágenes allí en lugar de en su servidor local.

     

    Para hacer eso, debemos ir a la carpeta donde está instalada nuestra instancia de Ghost y abrir el archivo: ghost.development.jsono ghost.production.json.(dependiendo del entorno que esté ejecutando actualmente)

    Entonces solo necesitamos agregar lo siguiente:

    { "storage": { "active": "s3", "s3": { "accessKeyId": "[key]", "secretAccessKey": "[secret]", "region": "[region]", "bucket": "[bucket]", "assetHost": "https://[subdomain].example.com", // cloudfront "forcePathStyle": true, "acl": "private" }}

    Los valores de accessKeyIdy secretAccessKeyse pueden encontrar en su configuración de IAM, mientras que la región y el depósito se refieren a la región y el nombre del depósito de su depósito S3. Finalmente, assetHostes la URL de su distribución de Cloudfront.

    Ahora, si reinicia su instancia de Ghost, verá que todas las imágenes nuevas que guarde están en su depósito S3 y Ghost sabe vincularlas allí. (Nota: Ghost no realizará actualizaciones retroactivamente, así que asegúrese de hacer esto primero después de una nueva instalación de Ghost para no tener que volver a cargar imágenes más tarde)

    Manejo de enlaces internos

    Una vez eliminadas las imágenes, el siguiente aspecto complicado en el que debemos pensar son los enlaces internos. Mientras escribe contenido en Ghost e inserta enlaces en publicaciones y páginas, Ghost agregará automáticamente la URL del sitio a todos los enlaces internos.

    Entonces, por ejemplo, si pones un enlace en la publicación de tu blog que va a /my-post/, Ghost creará un enlace que va a https://mysite.com/my-post/ .

    Normalmente, esto no es gran cosa, pero para los blogs sin cabeza esto causa problemas. Esto se debe a que su instancia de Ghost se alojará en un lugar separado de su interfaz y, en nuestro caso, ni siquiera será accesible en línea, ya que la construiremos localmente.

    Esto significa que tendremos que revisar cada publicación y página del blog para corregir los enlaces internos. Afortunadamente, esto no es tan difícil como parece.

    Primero, agregaremos este script de análisis HTML en un nuevo archivo llamado replaceLinks.jsy lo colocaremos en una nueva carpeta de utilidades en src/utils:

     

    const url = require(`url`);const cheerio = require('cheerio');const replaceLinks = async (htmlInput, siteUrlString) = { const siteUrl = url.parse(siteUrlString); const $ = cheerio.load(htmlInput); const links = $('a'); links.attr('href', function(i, href){ if (href) { const hrefUrl = url.parse(href); if (hrefUrl.protocol === siteUrl.protocol hrefUrl.host === siteUrl.host) { return hrefUrl.path } return href; } }); return $.html();}module.exports = replaceLinks;

    Luego agregaremos lo siguiente a nuestro gatsby-node.jsarchivo:

    exports.onCreateNode = async ({ actions, node, getNodesByType }) = { if (node.internal.owner !== `gatsby-source-ghost`) { return } if (node.internal.type === 'GhostPage' || node.internal.type === 'GhostPost') { const settings = getNodesByType(`GhostSettings`); actions.createNodeField({ name: 'html', value: replaceLinks(node.html, settings[0].url), node }) }}

    Verá que estamos agregando dos paquetes nuevos en replaceLinks.js, así que comencemos instalándolos con NPM:

    npm install --save url cheerio

    En nuestro gatsby-node.jsarchivo, nos estamos conectando a onCreateNode de Gatsby , y específicamente a cualquier nodo que se cree a partir de datos que provienen gatsby-source-ghost(a diferencia de los metadatos que provienen de nuestro archivo de configuración que no nos importan por ahora).

    Luego, verificamos el tipo de nodo para filtrar los nodos que no sean páginas o publicaciones fantasma (ya que estas son las únicas que tendrán enlaces dentro de su contenido).

    A continuación, obtenemos la URL del sitio Ghost de la configuración de Ghost y la pasamos a nuestra removeLinksfunción junto con el contenido HTML de la página/publicación.

    En replaceLinks, estamos usando cheerio para analizar el HTML. Luego podemos seleccionar todos los enlaces en este contenido HTML y mapear sus hrefatributos. Luego podemos verificar si el hrefatributo coincide con la URL del sitio fantasma; si es así, reemplazaremos el hrefatributo solo con la ruta URL, que es el enlace interno que estamos buscando (por ejemplo, algo como /my-post/).

    Finalmente, estamos haciendo que este nuevo contenido HTML esté disponible a través de GraphQL usando createNodeField de Gatsby (Nota: debemos hacerlo de esta manera ya que Gatsby no le permite sobrescribir campos en esta fase de la compilación).

    Ahora nuestro nuevo contenido HTML estará disponible en nuestra blog-post.jsplantilla y podremos acceder a él cambiando nuestra consulta GraphQL a:

    ghostPost(slug: { eq: $slug }) { id title slug excerpt published_at_pretty: published_at(formatString: "DD MMMM, YYYY") html meta_title fields { html } }

    Y con eso, sólo necesitamos modificar esta sección en la plantilla:

    section dangerouslySetInnerHTML={{ __html: post.html }} itemProp="articleBody"/

    Ser:

    section dangerouslySetInnerHTML={{ __html: post.fields.html }} itemProp="articleBody"/

    Esto hace que todos nuestros enlaces internos sean accesibles, pero todavía tenemos un problema más. Todos estos enlaces son aetiquetas de anclaje, mientras que con Gatsby deberíamos usar Gatsby Linkpara los enlaces internos (para evitar actualizaciones de la página y brindar una experiencia más fluida).

     

    Afortunadamente, existe un complemento de Gatsby que hace que esto sea realmente fácil de resolver. Se llama gatsby-plugin-catch-links y busca enlaces internos y reemplaza automáticamente las etiquetas de anclaje a con Gatsby Link.

    Todo lo que necesitamos hacer es instalarlo usando NPM:

    npm install --save gatsby-plugin-catch-links

    Y agréguelo gatsby-plugin-catch-linksa nuestra matriz de complementos en nuestro gatsby-configarchivo.

    Agregar plantillas y estilos

    Ahora las cosas importantes están funcionando técnicamente, pero nos estamos perdiendo parte del contenido de nuestra instancia de Ghost.

    El blog inicial de Gatsby solo tiene una página de índice y una plantilla para publicaciones de blog, mientras que Ghost tiene de forma predeterminada publicaciones, páginas, así como páginas para etiquetas y autores. Entonces necesitamos crear plantillas para cada uno de estos.

    Para ello podemos aprovechar el iniciador de Gatsby que fue creado por el equipo de Ghost .

    Como punto de partida para este proyecto, podemos simplemente copiar y pegar muchos de los archivos directamente en nuestro proyecto. Esto es lo que tomaremos:

    • La carpeta completa src/components/common/meta : la copiaremos en nuestra src/componentscarpeta (así que ahora tendremos una carpeta src/components/meta)
    • Los archivos componentes Pagination.js y PostCard.js : los copiaremos en nuestra src/componentscarpeta
    • Crearemos una src/utilscarpeta y agregaremos dos archivos de su src/utilscarpeta: fragments.js y siteConfig.js.
    • Y las siguientes plantillas de su src/templatescarpeta: tag.js , page.js , Author.js y post.js.

    Los metaarchivos agregan marcado de datos estructurados JSON a nuestras plantillas. Este es un gran beneficio que Ghost ofrece de forma predeterminada en su plataforma y lo han transpuesto a Gatsby como parte de su plantilla inicial. Horoscopos y tarot de amor

    Luego tomamos los componentes Paginationy PostCard.jsque podemos colocar directamente en nuestro proyecto. Y con esos componentes, podemos tomar los archivos de plantilla y colocarlos en nuestro proyecto y funcionarán.

    El fragments.jsarchivo hace que nuestras consultas GraphQL sean mucho más limpias para cada una de nuestras páginas y plantillas; ahora solo tenemos una fuente central para todas nuestras consultas GraphQL. Y el siteConfig.jsarchivo tiene algunas opciones de configuración de Ghost que son más fáciles de colocar en un archivo separado.

    Ahora sólo necesitaremos instalar algunos paquetes npm y actualizar nuestro gatsby-nodearchivo para usar nuestras nuevas plantillas.

    Los paquetes que necesitaremos instalar son gatsby-awesome-pagination , @tryghost/helpersy @tryghost/helpers-gatsby.

    Entonces haremos:

    npm install --save gatsby-awesome-pagination @tryghost/helpers @tryghost/helpers-gatsby

    Luego necesitamos hacer algunas actualizaciones en nuestro gatsby-nodearchivo.

     

    Primero, agregaremos las siguientes nuevas importaciones en la parte superior de nuestro archivo:

    const { paginate } = require(`gatsby-awesome-pagination`);const { postsPerPage } = require(`./src/utils/siteConfig`);

    A continuación, en nuestro exports.createPages, actualizaremos nuestra consulta GraphQL a:

    { allGhostPost(sort: { order: ASC, fields: published_at }) { edges { node { slug } } } allGhostTag(sort: { order: ASC, fields: name }) { edges { node { slug url postCount } } } allGhostAuthor(sort: { order: ASC, fields: name }) { edges { node { slug url postCount } } } allGhostPage(sort: { order: ASC, fields: published_at }) { edges { node { slug url } } }}

    Esto extraerá todos los datos de GraphQL que necesitamos para que Gatsby cree páginas basadas en nuestras nuevas plantillas.

    Para hacer eso, extraeremos todas esas consultas y las asignaremos a variables:

    // Extract query results const tags = result.data.allGhostTag.edges const authors = result.data.allGhostAuthor.edges const pages = result.data.allGhostPage.edges const posts = result.data.allGhostPost.edges

    Luego cargaremos todas nuestras plantillas:

    // Load templates const tagsTemplate = path.resolve(`./src/templates/tag.js`) const authorTemplate = path.resolve(`./src/templates/author.js`) const pageTemplate = path.resolve(`./src/templates/page.js`) const postTemplate = path.resolve(`./src/templates/post.js`)

    Tenga en cuenta que estamos reemplazando nuestra blog-post.jsplantilla anterior con post.js, para que podamos continuar y eliminarla blog-post.jsde nuestra carpeta de plantillas.

    Finalmente, agregaremos este código para crear páginas a partir de nuestras plantillas y datos GraphQL:

    // Create tag pagestags.forEach(({ node }) = { const totalPosts = node.postCount !== null ? node.postCount : 0 // This part here defines, that our tag pages will use // a `/tag/:slug/` permalink. const url = `/tag/${node.slug}` const items = Array.from({length: totalPosts}) // Create pagination paginate({ createPage, items: items, itemsPerPage: postsPerPage, component: tagsTemplate, pathPrefix: ({ pageNumber }) = (pageNumber === 0) ? url : `${url}/page`, context: { slug: node.slug } })})// Create author pagesauthors.forEach(({ node }) = { const totalPosts = node.postCount !== null ? node.postCount : 0 // This part here defines, that our author pages will use // a `/author/:slug/` permalink. const url = `/author/${node.slug}` const items = Array.from({length: totalPosts}) // Create pagination paginate({ createPage, items: items, itemsPerPage: postsPerPage, component: authorTemplate, pathPrefix: ({ pageNumber }) = (pageNumber === 0) ? url : `${url}/page`, context: { slug: node.slug } })})// Create pagespages.forEach(({ node }) = { // This part here defines, that our pages will use // a `/:slug/` permalink. node.url = `/${node.slug}/` createPage({ path: node.url, component: pageTemplate, context: { // Data passed to context is available // in page queries as GraphQL variables. slug: node.slug, }, })})// Create post pagesposts.forEach(({ node }) = { // This part here defines, that our posts will use // a `/:slug/` permalink. node.url = `/${node.slug}/` createPage({ path: node.url, component: postTemplate, context: { // Data passed to context is available // in page queries as GraphQL variables. slug: node.slug, }, })})

    Aquí, recorremos sucesivamente nuestras etiquetas, autores, páginas y publicaciones. Para nuestras páginas y publicaciones, simplemente creamos slugs y luego creamos una nueva página usando ese slug y le decimos a Gatsby qué plantilla usar.

     

    Para las etiquetas y las páginas de autor, también estamos agregando información de paginación gatsby-awesome-paginationque se pasará al archivo pageContext.

    Con eso, todo nuestro contenido ahora debería crearse y mostrarse correctamente. Pero nos vendría bien un poco de trabajo en el estilo. Como copiamos nuestras plantillas directamente desde Ghost Starter, también podemos usar sus estilos.

    No todos estos serán aplicables, pero para mantener las cosas simples y no atascarse demasiado en el estilo, tomé todos los estilos de src/styles/app.css de Ghost desde la sección Diseño hasta el final. Luego, simplemente los pegará al final de su src/styles.cssarchivo.

    Observe todos los estilos que comienzan con kg: esto se refiere a Koening, que es el nombre del editor Ghost. Estos estilos son muy importantes para las plantillas de Publicación y Página, ya que tienen estilos específicos que manejan el contenido que se crea en el editor Ghost. Estos estilos garantizan que todo el contenido que escribe en su editor se traduzca y se muestre correctamente en su blog.

    Por último, necesitamos nuestros archivos page.jsy post.jspara acomodar nuestro reemplazo de enlace interno del paso anterior, comenzando con las consultas:

    Page.js

    ghostPage(slug: { eq: $slug } ) { ...GhostPageFields fields { html }}

    Post.js

    ghostPost(slug: { eq: $slug } ) { ...GhostPostFields fields { html }}

    Y luego las secciones de nuestras plantillas que utilizan el contenido HTML. Entonces en nuestro post.jscambiaremos:

    sectionclassName="content-body load-external-scripts"dangerouslySetInnerHTML={{ __html: post.html }} /

    A:

    sectionclassName="content-body load-external-scripts"dangerouslySetInnerHTML={{ __html: post.fields.html }} /

    Y de manera similar, en nuestro page.jsarchivo, cambiaremos page.htmla page.fields.html.

    Contenido de página dinámica

    Una de las desventajas de Ghost cuando se utiliza como CMS tradicional es que no es posible editar piezas individuales de contenido en una página sin acceder a los archivos de temas reales y codificarlos.

     

    Supongamos que tiene una sección en su sitio que es un llamado a la acción o testimonios de clientes. Si desea cambiar el texto en estos cuadros, tendrá que editar los archivos HTML reales.

    Una de las mejores ventajas de utilizar el modo headless es que podemos crear contenido dinámico en nuestro sitio que podemos editar fácilmente con Ghost. Haremos esto usando páginas que marcaremos con etiquetas 'internas' o etiquetas que comienzan con un #símbolo.

    Entonces, como ejemplo, vayamos a nuestro backend de Ghost, creemos una nueva página llamada Mensaje, escribamos algo como contenido y, lo más importante, agregaremos la etiqueta #message.

    Ahora volvamos a nuestro gatsby-nodearchivo. Actualmente, estamos creando páginas para todas nuestras etiquetas y páginas, pero si modificamos nuestra consulta GraphQL en createPages, podemos excluir todo lo interno:

    allGhostTag(sort: { order: ASC, fields: name }, **filter: {slug: {regex: "/^((?!hash-).)*$/"}}**) { edges { node { slug url postCount } }}//...allGhostPage(sort: { order: ASC, fields: published_at }, **filter: {tags: {elemMatch: {slug: {regex: "/^((?!hash-).)*$/"}}}}**) { edges { node { slug url html } }}

    Estamos agregando un filtro en etiquetas slugs con la expresión regular /^((?!hash-).)*$/. Esta expresión dice que se excluyan cualquier etiqueta que incluya hash-.

    Ahora, no crearemos páginas para nuestro contenido interno, pero aún podemos acceder a él desde nuestras otras consultas GraphQL. Así que agreguémoslo a nuestra index.jspágina agregando esto a nuestra consulta:

    query GhostIndexQuery($limit: Int!, $skip: Int!) { site { siteMetadata { title } } message: ghostPage (tags: {elemMatch: {slug: {eq: "hash-message"}}}) { fields { html } } allGhostPost( sort: { order: DESC, fields: [published_at] }, limit: $limit, skip: $skip ) { edges { node { ...GhostPostFields } } } }

    Aquí estamos creando una nueva consulta llamada "mensaje" que busca nuestra página de contenido interno filtrando específicamente por etiqueta #message. Entonces usemos el contenido de nuestra página #message agregando esto a nuestra página:

    //...const BlogIndex = ({ data, location, pageContext }) = { const siteTitle = data.site.siteMetadata?.title || `Title` const posts = data.allGhostPost.edges const message = data.message;//...return ( Layout location={location} title={siteTitle} Seo / section dangerouslySetInnerHTML={{ __html: message.fields.html, }} / )}

    Últimos retoques

    Ahora tenemos una configuración de blog realmente excelente, pero podemos agregar algunos toques finales: paginación en nuestra página de índice, un mapa del sitio y un canal RSS.

    Primero, para agregar paginación, necesitaremos convertir nuestra index.jspágina en una plantilla. Todo lo que tenemos que hacer es cortar y pegar nuestro archivo index.js de nuestra src/pagescarpeta a nuestra carpeta src/templates y luego agregarlo a la sección donde cargamos nuestras plantillas gatsby-node.js:

     

    // Load templates const indexTemplate = path.resolve(`./src/templates/index.js`)

    Luego debemos decirle a Gatsby que cree nuestra página de índice con nuestra index.jsplantilla y decirle que cree el contexto de paginación.

    En total, agregaremos este código justo después de donde creamos nuestras páginas de publicación:

    // Create Index page with pagination paginate({ createPage, items: posts, itemsPerPage: postsPerPage, component: indexTemplate, pathPrefix: ({ pageNumber }) = { if (pageNumber === 0) { return `/` } else { return `/page` } }, })

    Ahora abramos nuestra index.jsplantilla, importemos nuestro componente Paginación y agréguelo justo debajo de donde asignamos nuestras publicaciones:

    import Pagination from '../components/pagination'//... /ol Pagination pageContext={pageContext} / /Layout//...

    Entonces solo necesitamos cambiar el enlace a las publicaciones de nuestro blog de:

    Link to={post.node.slug} itemProp="url"

    a:

    Link to={`/${post.node.slug}/`} itemProp="url"

    This prevents Gatsby Link from prefixing our links on pagination pages — in other words, if we didn’t do this, a link on page 2 would show as /page/2/my-post/ instead of just /my-post/ like we want.

    With that done, let’s set up our RSS feed. This is a pretty simple step, as we can use a ready-made script from the Ghost team’s Gatsby starter. Let’s copy their file generate-feed.js into our src/utils folder.

    Then let’s use it in our gatsby-config.js by replacing the existing gatsby-plugin-feed section with:

    { resolve: `gatsby-plugin-feed`, options: { query: ` { allGhostSettings { edges { node { title description } } } } `, feeds: [ generateRSSFeed(config), ], },}

    We will need to import our script along with our siteConfig.js file:

    const config = require(`./src/utils/siteConfig`);const generateRSSFeed = require(`./src/utils/generate-feed`);//...

    Finally, we need to make one important addition to our generate-feed.js file. Right after the GraphQL query and the output field, we need to add a title field:

    #...output: `/rss.xml`,title: "Gatsby Starter Blog RSS Feed",#...

    Without this title field, gatsby-plugin-feed will throw an error on the build.

    Then for our last finishing touch, let’s add our sitemap by installing the package gatsby-plugin-advanced-sitemap:

    npm install --save gatsby-plugin-advanced-sitemap

    And adding it to our gatsby-config.js file:

    { resolve: `gatsby-plugin-advanced-sitemap`, options: { query: ` { allGhostPost { edges { node { id slug updated_at created_at feature_image } } } allGhostPage { edges { node { id slug updated_at created_at feature_image } } } allGhostTag { edges { node { id slug 




    Tal vez te puede interesar:

    1. ¿Deberían abrirse los enlaces en ventanas nuevas?
    2. 24 excelentes tutoriales de AJAX
    3. 70 técnicas nuevas y útiles de AJAX y JavaScript
    4. Más de 45 excelentes recursos y repositorios de fragmentos de código

    La configuración de blog en solitario definitiva y gratuita con Ghost y Gatsby

    La configuración de blog en solitario definitiva y gratuita con Ghost y Gatsby

    Listas de verificación de diseño de interfaz inteligente Patrones de diseño de interfaces inteligentes, vídeo de 10h + formación UX Índice

    programar

    es

    https://aprendeprogramando.es/static/images/programar-la-configuracion-de-blog-en-solitario-definitiva-y-gratuita-con-ghost-y-gatsby-1143-0.jpg

    2024-04-04

     

    La configuración de blog en solitario definitiva y gratuita con Ghost y Gatsby
    La configuración de blog en solitario definitiva y gratuita con Ghost y Gatsby

    Si crees que alguno de los contenidos (texto, imagenes o multimedia) en esta página infringe tus derechos relativos a propiedad intelectual, marcas registradas o cualquier otro de tus derechos, por favor ponte en contacto con nosotros en el mail [email protected] y retiraremos este contenido inmediatamente

     

     

    Top 20