Foreword
Sometimes we really question the whole concept of blogging. Because it's almost become synonymous with: "how do I get my website to the front of Google". Whether you're of the camp of "I enjoy it and want to inform people" or "How many keywords can I pad out in this thinly veiled promotion-piece" - this is for you.
With that said, just be aware we want you to actually use this Chat GPT somewhat responsibly because, ultimately, you will make the web a better place for everybody if Google isn't linking to your affiliate-link-ridden "review" shop.
Prerequisites
We advise you to use GitHub as a social login for both Sanity and Vercel because it makes this whole process a lot easier.
- Have a Github account (or set one up during tutorial)
- Have a Vercel account (or set one up during tutorial)
- Have a Sanity account (or set one up during tutorial)
- Basic knowledge of deploying a website
- A code editor (just use VS Code)
Getting started
For this demo, we're going to be using the Sanity: Blog with Built-in Content Editing template. Click the deploy with Vercel. We're not going to run through how to set up a Vercel deployment, but if you get stuck, feel free to ping us on Sanity's community Slack or direct
Once this is done, you will have a Vercel environment, a Sanity Studio environment and a repo with Next.js and Sanity within it. Congratulations.
If you navigate to the URL, you should find a website that looks similar to the above. It has your Sanity Studio details and your Github Repo details. Click on the "Go to Sanity Studio" button and "Go to GitHub Repo" (save the GitHub repo in another tab for later, for now, we will focus on the Sanity CMS setup).
On the Sanity link, you should see a screen that looks like this:
Make sure you've added this to your Sanity management. You can do so by pressing the continue button. It should take you directly to the page you need. However, if it doesn't, you can navigate there by going to https://manage.sanity.io/ and then following the links below.
*Project Name* > Settings > API Settings > CORS Origins
Once you have that sorted, the screen should change to something similar to the below:
Login, and once you're there, you should be able to start adding plugins. This brings us to the GitHub link from earlier. Navigate there and clone it to your local computer.
Wherever you've now cloned that, open it in your code editor. You're looking for a file called "sanity.config.ts".
Open this up, and you should see some code that looks nearly identical to this:
/*** This config is used to set up Sanity Studio that's mounted on the `/pages/studio/[[...index]].tsx` route*/import { visionTool } from '@sanity/vision'import { apiVersion, dataset, previewSecretId, projectId } from 'lib/sanity.api'import { previewDocumentNode } from 'plugins/previewPane'import { productionUrl } from 'plugins/productionUrl'import { settingsPlugin, settingsStructure } from 'plugins/settings'import { defineConfig } from 'sanity'import { deskTool } from 'sanity/desk'import { unsplashImageAsset } from 'sanity-plugin-asset-source-unsplash'import authorType from 'schemas/author'import postType from 'schemas/post'import settingsType from 'schemas/settings'const title =process.env.NEXT_PUBLIC_SANITY_PROJECT_TITLE || 'Next.js Blog with Sanity.io'export default defineConfig({basePath: '/studio',projectId,dataset,title,schema: {// If you want more content types, you can add them to this arraytypes: [authorType, postType, settingsType],},plugins: [deskTool({structure: settingsStructure(settingsType),// `defaultDocumentNode` is responsible for adding a “Preview” tab to the document panedefaultDocumentNode: previewDocumentNode({ apiVersion, previewSecretId }),}),// Configures the global "new document" button, and document actions, to suit the Settings document singletonsettingsPlugin({ type: settingsType.name }),// Add the "Open preview" actionproductionUrl({apiVersion,previewSecretId,types: [postType.name, settingsType.name],}),// Add an image asset source for UnsplashunsplashImageAsset(),// Vision lets you query your content with GROQ in the studio// https://www.sanity.io/docs/the-vision-pluginvisionTool({ defaultApiVersion: apiVersion }),],})
We are going to be adding two plugins. One for Chat GPT and one for Dall.e style image generation. Both of them using Open AI's API.
To save you tracking them down, we've included a direct copy and paste job with the two plugins.
Run this from the root of your project:
npm i sanity-plugin-chat-gpt sanity-plugin-asset-source-openai
Once that's finished, replace the "sanity.config.ts" config file from earlier with the code below.
/*** This config is used to set up Sanity Studio that's mounted on the `/pages/studio/[[...index]].tsx` route*/import { visionTool } from '@sanity/vision'import { apiVersion, dataset, previewSecretId, projectId } from 'lib/sanity.api'import { previewDocumentNode } from 'plugins/previewPane'import { productionUrl } from 'plugins/productionUrl'import { settingsPlugin, settingsStructure } from 'plugins/settings'import { defineConfig } from 'sanity'import { deskTool } from 'sanity/desk'import { openaiImageAsset } from 'sanity-plugin-asset-source-openai'import { unsplashImageAsset } from 'sanity-plugin-asset-source-unsplash'import { chatGPT } from 'sanity-plugin-chat-gpt'import authorType from 'schemas/author'import postType from 'schemas/post'import settingsType from 'schemas/settings'const title =process.env.NEXT_PUBLIC_SANITY_PROJECT_TITLE || 'Next.js Blog with Sanity.io'const API_KEY = 'YOUR_API_KEY_HERE'export default defineConfig({basePath: '/studio',projectId,dataset,title,schema: {// If you want more content types, you can add them to this arraytypes: [authorType, postType, settingsType],},plugins: [deskTool({structure: settingsStructure(settingsType),// `defaultDocumentNode` is responsible for adding a “Preview” tab to the document panedefaultDocumentNode: previewDocumentNode({ apiVersion, previewSecretId }),}),// Configures the global "new document" button, and document actions, to suit the Settings document singletonsettingsPlugin({ type: settingsType.name }),// Add the "Open preview" actionproductionUrl({apiVersion,previewSecretId,types: [postType.name, settingsType.name],}),// Add an image asset source for UnsplashunsplashImageAsset(),chatGPT({API_KEY,}),openaiImageAsset({API_KEY,}),// Vision lets you query your content with GROQ in the studio// https://www.sanity.io/docs/the-vision-pluginvisionTool({ defaultApiVersion: apiVersion }),],})
If you're looking at adding the code to your own project the only bits you need are the imports, the API key definition and the plugins. For that it should look like this below
import { openaiImageAsset } from 'sanity-plugin-asset-source-openai'import { chatGPT } from 'sanity-plugin-chat-gpt'const API_KEY = 'YOUR_API_KEY_HERE'export default defineConfig({...plugins: [chatGPT({API_KEY,}),openaiImageAsset({API_KEY,}),],...})
Adding an API key from Open AI
Go to this link and create an account. Once you've got an account, you will need to go enter payment details for your Open AI usage. Trust me when I say, "it's more than worth it, and we shaved hours off our writing time for a couple of quid".
Once you've sorted payment details you can get yourself an API key here. Use this key to replace the line "YOUR_API_KEY_HERE" within the code example above.
Running Sanity + Next.js locally
Once you've got this up and running, the next step should be easy (fingers crossed).
Run your Sanity + Next.js website locally by running "npm run dev" from your terminal. You will need to run through this short set of steps to get it running.
Using Chat GPT + Image generation Inside of Sanity Studio
So the fact your reading further leads me to believe that you've got the localhost version of the website running. So let's start playing around with the brand-new tools we've got.
First off, open create a brand-new post
Using Open AI Image Generation inside of Sanity
Now that you have a new post document, you can start playing with the latest tools.
You can find "Open AI image generation" by pressing Select on the right-hand side of the image inside of the post. Click it.
This will give you a popup modal that allows you to enter just about any type of prompt you want. For example, we use this to populate our blog. We use "a cat in victorian clothing, in the style of an oil painting". From there, you can either press generate again if you don't like the results or confirm if you're happy with them.
Using Chat GPT plugin directly in Sanity
Now that you've sorted the cover image for the document, you can look at that pesky blog content. Why don't we start by writing an outline using the plugin?
How to add to Portable Text
There's an extra step to add ChatGPT, which requires you to do a little bit of code. But don't worry; it's literally just four lines - two of which are brackets...
Go to the post.ts file, and inside of the block schema, add the name and type of "chatGPT". Or, if you're lazy, just copy and paste in the code from here. Pay close attention to lines 49 & 50.
import { BookIcon } from '@sanity/icons'import { format, parseISO } from 'date-fns'import { defineField, defineType } from 'sanity'import authorType from './author'/*** This file is the schema definition for a post.** Here you'll be able to edit the different fields that appear when you* create or edit a post in the studio.** Here you can see the different schema types that are available:https://www.sanity.io/docs/schema-types*/export default defineType({name: 'post',title: 'Post',icon: BookIcon,type: 'document',fields: [defineField({name: 'title',title: 'Title',type: 'string',validation: (rule) => rule.required(),}),defineField({name: 'slug',title: 'Slug',type: 'slug',options: {source: 'title',maxLength: 96,isUnique: (value, context) => context.defaultIsUnique(value, context),},validation: (rule) => rule.required(),}),defineField({name: 'content',title: 'Content',type: 'array',of: [{ type: 'block' },{name: 'chatGPT',type: 'chatGPT',},],}),defineField({name: 'excerpt',title: 'Excerpt',type: 'text',}),defineField({name: 'coverImage',title: 'Cover Image',type: 'image',options: {hotspot: true,},}),defineField({name: 'date',title: 'Date',type: 'datetime',initialValue: () => new Date().toISOString(),}),defineField({name: 'author',title: 'Author',type: 'reference',to: [{ type: authorType.name }],}),],preview: {select: {title: 'title',author: 'author.name',date: 'date',media: 'coverImage',},prepare({ title, media, author, date }) {const subtitles = [author && `by ${author}`,date && `on ${format(parseISO(date), 'LLL d, yyyy')}`,].filter(Boolean)return { title, media, subtitle: subtitles.join(' ') }},},})
This works with any portable text you may have throughout your schema, so simply adding chatGpt like above will make it appear.
Start generating outlines
We would advise you to use ChatGPT sparingly because we suspect a bot-apocalypse is coming from the Google search rankings side... Despite what buzzfeed is doing.
So write yourself a prompt for an outline of an article. Then press generate.
Now thanks to the help of Chat GPT, you can write a well-structured article that doesn't waffle on and sound barely coherent. We should take notes...
Final thoughts
We said it in the first paragraph and we'll reiterate in the last: "Don't just use this for spewing out endless surface-level content"; you will make the web-world a worse place.
Use it for writer's block, and tailor it and curate it to help people, enthuse people and... Who am I kidding, can't wait to read your Affiliate links on the first page of Google.