├── demo ├── src │ ├── env.d.ts │ ├── components │ │ └── PortableText.astro │ ├── sanity │ │ ├── urlForImage.js │ │ ├── api.js │ │ └── portableText.js │ └── pages │ │ └── index.astro ├── tsconfig.json ├── .npmrc ├── .stackblitzrc ├── .vscode │ ├── extensions.json │ └── launch.json ├── sandbox.config.json ├── .gitignore ├── astro.config.mjs ├── package.json ├── public │ └── favicon.svg └── README.md ├── .gitignore ├── demo-ssr ├── src │ ├── env.d.ts │ ├── components │ │ └── PortableText.astro │ ├── sanity │ │ ├── urlForImage.js │ │ ├── api.js │ │ └── portableText.js │ └── pages │ │ └── index.astro ├── tsconfig.json ├── .npmrc ├── .stackblitzrc ├── .vscode │ ├── extensions.json │ └── launch.json ├── sandbox.config.json ├── .gitignore ├── package.json ├── astro.config.mjs ├── public │ └── favicon.svg └── README.md ├── src ├── groq │ └── index.ts ├── createSanityClient │ └── index.ts ├── portableTextToHtml │ └── index.ts ├── createImageBuilder │ └── index.ts ├── tsconfig.json ├── vite.config.ts ├── vite-plugin-sanity-init.ts ├── index.ts ├── package.json └── README.md ├── package.json ├── LICENSE └── README.md /demo/src/env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | 3 | dist/ 4 | 5 | package-lock.json -------------------------------------------------------------------------------- /demo-ssr/src/env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /src/groq/index.ts: -------------------------------------------------------------------------------- 1 | import groq from 'groq' 2 | 3 | export {groq}; -------------------------------------------------------------------------------- /demo/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "astro/tsconfigs/base" 3 | } 4 | -------------------------------------------------------------------------------- /demo-ssr/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "astro/tsconfigs/base" 3 | } 4 | -------------------------------------------------------------------------------- /demo/.npmrc: -------------------------------------------------------------------------------- 1 | # Expose Astro dependencies for `pnpm` users 2 | shamefully-hoist=true 3 | -------------------------------------------------------------------------------- /demo-ssr/.npmrc: -------------------------------------------------------------------------------- 1 | # Expose Astro dependencies for `pnpm` users 2 | shamefully-hoist=true 3 | -------------------------------------------------------------------------------- /demo/.stackblitzrc: -------------------------------------------------------------------------------- 1 | { 2 | "startCommand": "npm start", 3 | "env": { 4 | "ENABLE_CJS_IMPORTS": true 5 | } 6 | } -------------------------------------------------------------------------------- /demo-ssr/.stackblitzrc: -------------------------------------------------------------------------------- 1 | { 2 | "startCommand": "npm start", 3 | "env": { 4 | "ENABLE_CJS_IMPORTS": true 5 | } 6 | } -------------------------------------------------------------------------------- /demo/.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": ["astro-build.astro-vscode"], 3 | "unwantedRecommendations": [] 4 | } 5 | -------------------------------------------------------------------------------- /demo-ssr/.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": ["astro-build.astro-vscode"], 3 | "unwantedRecommendations": [] 4 | } 5 | -------------------------------------------------------------------------------- /demo-ssr/src/components/PortableText.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import { sanityPortableText } from '../sanity/portableText' 3 | 4 | const {portableText} = Astro.props; 5 | --- 6 | 7 | -------------------------------------------------------------------------------- /demo/src/components/PortableText.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import { sanityPortableText } from '../sanity/portableText' 3 | 4 | const {portableText} = Astro.props; 5 | --- 6 | 7 | -------------------------------------------------------------------------------- /src/createSanityClient/index.ts: -------------------------------------------------------------------------------- 1 | import { createClient, ClientConfig, SanityClient } from '@sanity/client'; 2 | 3 | export function createSanityClient(config: ClientConfig): SanityClient { 4 | return createClient(config); 5 | } -------------------------------------------------------------------------------- /src/portableTextToHtml/index.ts: -------------------------------------------------------------------------------- 1 | import { toHTML } from '@portabletext/to-html'; 2 | 3 | export function portableTextToHtml(portabletext: any, customComponents = {}) { 4 | return toHTML(portabletext, { components: customComponents }); 5 | } -------------------------------------------------------------------------------- /src/createImageBuilder/index.ts: -------------------------------------------------------------------------------- 1 | import imageBuilder from '@sanity/image-url'; 2 | 3 | import { SanityClientLike } from '@sanity/image-url/lib/types/types'; 4 | 5 | export function createImageBuilder(client: SanityClientLike){ 6 | return imageBuilder(client); 7 | } -------------------------------------------------------------------------------- /demo/sandbox.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "infiniteLoopProtection": true, 3 | "hardReloadOnChange": false, 4 | "view": "browser", 5 | "template": "node", 6 | "container": { 7 | "port": 3000, 8 | "startScript": "start", 9 | "node": "14" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /demo-ssr/sandbox.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "infiniteLoopProtection": true, 3 | "hardReloadOnChange": false, 4 | "view": "browser", 5 | "template": "node", 6 | "container": { 7 | "port": 3000, 8 | "startScript": "start", 9 | "node": "14" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /demo/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | { 5 | "command": "./node_modules/.bin/astro dev", 6 | "name": "Development server", 7 | "request": "launch", 8 | "type": "node-terminal" 9 | } 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /demo-ssr/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | { 5 | "command": "./node_modules/.bin/astro dev", 6 | "name": "Development server", 7 | "request": "launch", 8 | "type": "node-terminal" 9 | } 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /demo/src/sanity/urlForImage.js: -------------------------------------------------------------------------------- 1 | import { useSanityClient } from 'astro-sanity'; 2 | import { createImageBuilder } from 'astro-sanity'; 3 | 4 | export const imageBuilder = createImageBuilder(useSanityClient()); 5 | 6 | export function urlForImage(source) { 7 | return imageBuilder.image(source); 8 | } 9 | -------------------------------------------------------------------------------- /demo-ssr/src/sanity/urlForImage.js: -------------------------------------------------------------------------------- 1 | import { useSanityClient } from 'astro-sanity'; 2 | import { createImageBuilder } from 'astro-sanity'; 3 | 4 | export const imageBuilder = createImageBuilder(useSanityClient()); 5 | 6 | export function urlForImage(source) { 7 | return imageBuilder.image(source); 8 | } 9 | -------------------------------------------------------------------------------- /demo/.gitignore: -------------------------------------------------------------------------------- 1 | # build output 2 | dist/ 3 | 4 | # dependencies 5 | node_modules/ 6 | 7 | # logs 8 | npm-debug.log* 9 | yarn-debug.log* 10 | yarn-error.log* 11 | pnpm-debug.log* 12 | 13 | 14 | # environment variables 15 | .env 16 | .env.production 17 | 18 | # macOS-specific files 19 | .DS_Store 20 | -------------------------------------------------------------------------------- /demo/src/sanity/api.js: -------------------------------------------------------------------------------- 1 | import { useSanityClient, groq } from 'astro-sanity'; 2 | 3 | export async function getFirstBlogPost() { 4 | const query = groq`*[_type == "post" && _id == "0b3a877f-9ede-4360-a7b0-dee96107215e"][0]`; 5 | const firstPost = await useSanityClient().fetch(query); 6 | return firstPost; 7 | } 8 | -------------------------------------------------------------------------------- /demo-ssr/.gitignore: -------------------------------------------------------------------------------- 1 | # build output 2 | dist/ 3 | 4 | # dependencies 5 | node_modules/ 6 | 7 | # logs 8 | npm-debug.log* 9 | yarn-debug.log* 10 | yarn-error.log* 11 | pnpm-debug.log* 12 | 13 | 14 | # environment variables 15 | .env 16 | .env.production 17 | 18 | # macOS-specific files 19 | .DS_Store 20 | 21 | .vercel/ -------------------------------------------------------------------------------- /demo-ssr/src/sanity/api.js: -------------------------------------------------------------------------------- 1 | import { useSanityClient } from 'astro-sanity'; 2 | import { groq } from 'astro-sanity'; 3 | 4 | export async function getFirstBlogPost() { 5 | const query = groq`*[_type == "post" && _id == "0b3a877f-9ede-4360-a7b0-dee96107215e"][0]`; 6 | const firstPost = await useSanityClient().fetch(query); 7 | return firstPost; 8 | } 9 | -------------------------------------------------------------------------------- /demo/astro.config.mjs: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'astro/config'; 2 | import sanity from 'astro-sanity' 3 | // https://astro.build/config 4 | export default defineConfig({ 5 | integrations: [ 6 | sanity({ 7 | projectId: '8hj1t7km', 8 | dataset: 'production', 9 | apiVersion: '2021-03-25', 10 | useCdn: true, 11 | })], 12 | }); -------------------------------------------------------------------------------- /demo/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "astro-sanity-demo", 3 | "version": "0.0.1", 4 | "private": true, 5 | "scripts": { 6 | "dev": "astro dev", 7 | "start": "astro dev", 8 | "build": "astro build", 9 | "preview": "astro preview", 10 | "astro": "astro" 11 | }, 12 | "devDependencies": { 13 | "astro": "^2.0.4", 14 | "astro-sanity": "^1.1.3" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "declaration": true, 4 | "target": "ES2020", 5 | "module": "ES2020", 6 | "outDir": "./dist", 7 | "strict": true, 8 | "moduleResolution": "node", 9 | "esModuleInterop": true, 10 | "skipLibCheck": true, 11 | "forceConsistentCasingInFileNames": true, 12 | "noImplicitAny": false 13 | }, 14 | "include": ["./**/*.ts"], 15 | } -------------------------------------------------------------------------------- /demo-ssr/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "astro-sanity-demo-ssr", 3 | "version": "0.0.1", 4 | "private": true, 5 | "scripts": { 6 | "dev": "astro dev", 7 | "start": "astro dev", 8 | "build": "astro build", 9 | "preview": "astro preview", 10 | "astro": "astro" 11 | }, 12 | "devDependencies": { 13 | "@astrojs/vercel": "^3.0.0", 14 | "astro": "^2.0.4", 15 | "astro-sanity": "^1.1.3" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /demo-ssr/astro.config.mjs: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'astro/config'; 2 | import vercel from '@astrojs/vercel/serverless'; 3 | import sanity from 'astro-sanity' 4 | 5 | // https://astro.build/config 6 | export default defineConfig({ 7 | output: 'server', 8 | adapter: vercel(), 9 | integrations: [ sanity({ 10 | projectId: '8hj1t7km', 11 | dataset: 'production', 12 | apiVersion: '2021-03-25', 13 | useCdn: true 14 | })], 15 | }); -------------------------------------------------------------------------------- /src/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from "vite"; 2 | import path from "path"; 3 | import dts from "vite-plugin-dts"; 4 | 5 | const name = "astro-sanity"; 6 | 7 | export default defineConfig(() => { 8 | return { 9 | plugins: [dts()], 10 | build: { 11 | lib: { 12 | entry: path.resolve(__dirname, "index.ts"), 13 | name: "astro-sanity", 14 | fileName: (format) => (format === "es" ? `${name}.mjs` : `${name}.js`), 15 | }, 16 | }} 17 | }); 18 | -------------------------------------------------------------------------------- /src/vite-plugin-sanity-init.ts: -------------------------------------------------------------------------------- 1 | import { ClientConfig } from "@sanity/client"; 2 | 3 | export function vitePluginSanityInit(config: ClientConfig) { 4 | const virtualModuleId = "virtual:sanity-init"; 5 | const resolvedVirtualModuleId = "\0" + virtualModuleId; 6 | 7 | return { 8 | name: "vite-plugin-sanity-init", 9 | async resolveId(id: string) { 10 | if (id === virtualModuleId) { 11 | return resolvedVirtualModuleId; 12 | } 13 | }, 14 | async load(id: string) { 15 | if (id === resolvedVirtualModuleId) { 16 | return ` 17 | import {createClient} from "@sanity/client"; 18 | export const sanityClient = createClient(${JSON.stringify(config)}); 19 | `; 20 | } 21 | }, 22 | }; 23 | } 24 | -------------------------------------------------------------------------------- /demo-ssr/src/sanity/portableText.js: -------------------------------------------------------------------------------- 1 | import { portableTextToHtml } from 'astro-sanity'; 2 | import { urlForImage } from './urlForImage'; 3 | 4 | const customComponents = { 5 | types: { 6 | image: ({ value }) => { 7 | return ` 8 | 9 | 13 | ${value.alt} 18 | 19 | `; 20 | }, 21 | }, 22 | }; 23 | 24 | export function sanityPortableText(portabletext) { 25 | return portableTextToHtml(portabletext, customComponents); 26 | } 27 | -------------------------------------------------------------------------------- /demo/src/sanity/portableText.js: -------------------------------------------------------------------------------- 1 | import { portableTextToHtml } from 'astro-sanity'; 2 | import { urlForImage } from './urlForImage'; 3 | 4 | const customComponents = { 5 | types: { 6 | image: ({ value }) => { 7 | return ` 8 | 9 | 13 | ${value.alt} 18 | 19 | `; 20 | }, 21 | }, 22 | }; 23 | 24 | export function sanityPortableText(portabletext) { 25 | return portableTextToHtml(portabletext, customComponents); 26 | } 27 | -------------------------------------------------------------------------------- /demo/public/favicon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 13 | 14 | -------------------------------------------------------------------------------- /demo-ssr/public/favicon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 13 | 14 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "astro-sanity", 3 | "version": "1.1.7", 4 | "description": "A helper package to integrate Astro and Sanity", 5 | "license": "MIT", 6 | "globals": { 7 | "globalThis": true 8 | }, 9 | "workspaces": [ 10 | "./src", 11 | "./demo", 12 | "./demo-ssr" 13 | ], 14 | "scripts": { 15 | "dev": "npm run dev --workspace=src", 16 | "demo": "npm run dev --workspace=demo", 17 | "demo-ssr": "npm run dev --workspace=demo-ssr", 18 | "build": "npm run build --workspace=src", 19 | "build-demo": "npm run build --workspace=demo", 20 | "build-ssr": "npm run build --workspace=demo-ssr", 21 | "clean": "npm run clean --workspace=src", 22 | "prebuild": "npm run clean --workspace=src", 23 | "prepublishOnly": "npm run build --workspace=src", 24 | "test": "echo \"Error: no test specified\" && exit 1" 25 | }, 26 | "author": "Jaydan Urwin", 27 | "repository": { 28 | "type": "git", 29 | "url": "https://github.com/littlesticks/astro-sanity" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2022 White Pine Studio, LLC 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 8 | 9 | -------------------------------------------------------------------------------- /demo/src/pages/index.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import PortableText from '../components/PortableText.astro'; 3 | import { urlForImage } from '../sanity/urlForImage'; 4 | import { getFirstBlogPost } from '../sanity/api'; 5 | 6 | const data = await getFirstBlogPost(); 7 | --- 8 | 9 | 22 | 23 | 24 | 25 | 26 | 27 | Astro 28 | 29 | 30 |
31 |

{data.title}

32 | 33 | 37 | 38 | 39 | 40 |
41 | 42 | -------------------------------------------------------------------------------- /demo-ssr/src/pages/index.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import PortableText from '../components/PortableText.astro'; 3 | import { urlForImage } from '../sanity/urlForImage'; 4 | import { getFirstBlogPost } from '../sanity/api'; 5 | 6 | const data = await getFirstBlogPost(); 7 | --- 8 | 9 | 22 | 23 | 24 | 25 | 26 | 27 | Astro SSR 28 | 29 | 30 |
31 |

{data.title}

32 | 33 | 37 | 38 | 39 | 40 |
41 | 42 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import { ClientConfig, SanityClient } from "@sanity/client"; 2 | import { AstroIntegration } from "astro"; 3 | 4 | export { createImageBuilder } from "./createImageBuilder/index.js"; 5 | export { portableTextToHtml } from "./portableTextToHtml/index.js"; 6 | export { createSanityClient } from "./createSanityClient/index.js"; 7 | export { groq } from "./groq/index.js"; 8 | 9 | import { vitePluginSanityInit } from "./vite-plugin-sanity-init.js"; 10 | 11 | export function useSanityClient() { 12 | if (!globalThis.sanityClient) { 13 | console.error("Sanity client has not been initialized correctly"); 14 | } 15 | 16 | return globalThis.sanityClient as SanityClient; 17 | } 18 | 19 | export default function astroSanityIntegration( 20 | options: ClientConfig, 21 | ): AstroIntegration { 22 | return { 23 | name: "astro-sanity", 24 | hooks: { 25 | "astro:config:setup": ({ injectScript, updateConfig }) => { 26 | updateConfig({ 27 | vite: { 28 | plugins: [ 29 | vitePluginSanityInit(options), 30 | ], 31 | }, 32 | }); 33 | injectScript( 34 | "page-ssr", 35 | ` 36 | import { sanityClient } from "virtual:sanity-init"; 37 | globalThis.sanityClient = sanityClient; 38 | `, 39 | ); 40 | }, 41 | }, 42 | }; 43 | } 44 | -------------------------------------------------------------------------------- /src/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "astro-sanity", 3 | "version": "1.1.7", 4 | "description": "A helper package to integrate Astro and Sanity", 5 | "license": "MIT", 6 | "type": "module", 7 | "main": "./dist/astro-sanity.js", 8 | "module": "./dist/astro-sanity.mjs", 9 | "types": "./dist/index.d.ts", 10 | "exports": { 11 | ".": { 12 | "import": "./dist/astro-sanity.mjs", 13 | "require": "./dist/astro-sanity.js" 14 | } 15 | }, 16 | "files": [ 17 | "dist" 18 | ], 19 | "globals": { 20 | "globalThis": true 21 | }, 22 | "scripts": { 23 | "dev": "vite build --watch", 24 | "build": "vite build", 25 | "clean": "rm -rf dist", 26 | "prebuild": "npm run clean", 27 | "prepublishOnly": "npm run clean && npm run build && cp ../README.md ./", 28 | "test": "echo \"Error: no test specified\" && exit 1" 29 | }, 30 | "keywords": [ 31 | "astro", 32 | "sanity", 33 | "sanity.io", 34 | "astro-integration", 35 | "astro-component" 36 | ], 37 | "author": "Jaydan Urwin", 38 | "dependencies": { 39 | "@portabletext/to-html": "^1.0.3", 40 | "@sanity/client": "^5.4.2", 41 | "@sanity/image-url": "^1.0.2", 42 | "astro": "^2.3.3", 43 | "groq": "^2.33.2" 44 | }, 45 | "devDependencies": { 46 | "@types/node": "^18.7.13", 47 | "typescript": "^4.8.2", 48 | "vite-plugin-dts": "^1.7.1" 49 | }, 50 | "repository": { 51 | "type": "git", 52 | "url": "https://github.com/littlesticks/astro-sanity" 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /demo/README.md: -------------------------------------------------------------------------------- 1 | # Astro Starter Kit: Minimal 2 | 3 | ``` 4 | npm init astro -- --template minimal 5 | ``` 6 | 7 | [![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/withastro/astro/tree/latest/examples/minimal) 8 | 9 | > 🧑‍🚀 **Seasoned astronaut?** Delete this file. Have fun! 10 | 11 | ## 🚀 Project Structure 12 | 13 | Inside of your Astro project, you'll see the following folders and files: 14 | 15 | ``` 16 | / 17 | ├── public/ 18 | ├── src/ 19 | │ └── pages/ 20 | │ └── index.astro 21 | └── package.json 22 | ``` 23 | 24 | Astro looks for `.astro` or `.md` files in the `src/pages/` directory. Each page is exposed as a route based on its file name. 25 | 26 | There's nothing special about `src/components/`, but that's where we like to put any Astro/React/Vue/Svelte/Preact components. 27 | 28 | Any static assets, like images, can be placed in the `public/` directory. 29 | 30 | ## 🧞 Commands 31 | 32 | All commands are run from the root of the project, from a terminal: 33 | 34 | | Command | Action | 35 | | :--------------------- | :----------------------------------------------- | 36 | | `npm install` | Installs dependencies | 37 | | `npm run dev` | Starts local dev server at `localhost:3000` | 38 | | `npm run build` | Build your production site to `./dist/` | 39 | | `npm run preview` | Preview your build locally, before deploying | 40 | | `npm run astro ...` | Run CLI commands like `astro add`, `astro check` | 41 | | `npm run astro --help` | Get help using the Astro CLI | 42 | 43 | ## 👀 Want to learn more? 44 | 45 | Feel free to check [our documentation](https://docs.astro.build) or jump into our [Discord server](https://astro.build/chat). 46 | -------------------------------------------------------------------------------- /demo-ssr/README.md: -------------------------------------------------------------------------------- 1 | # Astro Starter Kit: Minimal 2 | 3 | ``` 4 | npm init astro -- --template minimal 5 | ``` 6 | 7 | [![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/withastro/astro/tree/latest/examples/minimal) 8 | 9 | > 🧑‍🚀 **Seasoned astronaut?** Delete this file. Have fun! 10 | 11 | ## 🚀 Project Structure 12 | 13 | Inside of your Astro project, you'll see the following folders and files: 14 | 15 | ``` 16 | / 17 | ├── public/ 18 | ├── src/ 19 | │ └── pages/ 20 | │ └── index.astro 21 | └── package.json 22 | ``` 23 | 24 | Astro looks for `.astro` or `.md` files in the `src/pages/` directory. Each page is exposed as a route based on its file name. 25 | 26 | There's nothing special about `src/components/`, but that's where we like to put any Astro/React/Vue/Svelte/Preact components. 27 | 28 | Any static assets, like images, can be placed in the `public/` directory. 29 | 30 | ## 🧞 Commands 31 | 32 | All commands are run from the root of the project, from a terminal: 33 | 34 | | Command | Action | 35 | | :--------------------- | :----------------------------------------------- | 36 | | `npm install` | Installs dependencies | 37 | | `npm run dev` | Starts local dev server at `localhost:3000` | 38 | | `npm run build` | Build your production site to `./dist/` | 39 | | `npm run preview` | Preview your build locally, before deploying | 40 | | `npm run astro ...` | Run CLI commands like `astro add`, `astro check` | 41 | | `npm run astro --help` | Get help using the Astro CLI | 42 | 43 | ## 👀 Want to learn more? 44 | 45 | Feel free to check [our documentation](https://docs.astro.build) or jump into our [Discord server](https://astro.build/chat). 46 | -------------------------------------------------------------------------------- /src/README.md: -------------------------------------------------------------------------------- 1 | # Astro + Sanity Integration 2 | 3 | This is a helper package for integrating [Sanity](https://www.sanity.io/) with [Astro](https://astro.build/). It is not officially from Sanity but it is architected in the same way their official packages for frameworks like NextJS are. 4 | 5 | ## Installation 6 | 7 | ```bash 8 | npx astro add astro-sanity 9 | ``` 10 | 11 | Follow the prompts and once it's finished you should have something like the following in your `astro.config.mjs` file: 12 | 13 | ```js 14 | import sanity from 'astro-sanity' 15 | 16 | ... 17 | 18 | export default defineConfig({ 19 | integrations: [sanity()], 20 | }); 21 | ``` 22 | 23 | Update the sanity config to match your Sanity Client Config like so: 24 | 25 | ```js 26 | export default defineConfig({ 27 | integrations: [ 28 | sanity({ 29 | projectId: 'YOUR_PROJECT_ID', 30 | dataset: 'production', 31 | apiVersion: '2021-03-25', 32 | useCdn: true, 33 | })], 34 | }); 35 | ``` 36 | 37 | ## Usage 38 | 39 | Please see the [`/demo`](https://github.com/littlesticks/astro-sanity/tree/main/demo) for a full example. However, this package was designed to give you the building blocks to integrate with Sanity but the flexibility to implement it how you want with the helper function names and behavior you want. 40 | 41 | ### Using the Client 42 | 43 | You can globally use the Sanity Client from the config with the following import 44 | 45 | ```js 46 | import { useSanityClient } from 'astro-sanity'; 47 | ``` 48 | 49 | ### Querying Sanity with your Client 50 | 51 | Here is an example using the client to query Sanity: 52 | 53 | ```js 54 | import { useSanityClient, groq } from 'astro-sanity'; 55 | 56 | export async function getFirstBlogPost() { 57 | const query = groq`*[_type == "post"]`; 58 | const firstPost = await useSanityClient().fetch(query); 59 | return firstPost; 60 | } 61 | ``` 62 | 63 | ### Create Your own Image Builder Helper 64 | 65 | You can learn more about Sanity's image builder [here](https://www.sanity.io/docs/image-url). Here is an example of how you can create your own helper function to use in your components: 66 | 67 | ```js 68 | import { useSanityClient } from 'astro-sanity'; 69 | import { createImageBuilder } from 'astro-sanity'; 70 | 71 | export const imageBuilder = createImageBuilder(useSanityClient()); 72 | 73 | export function urlForImage(source) { 74 | return imageBuilder.image(source); 75 | } 76 | ``` 77 | 78 | ### Create a Custom portableTextToHtml Serializer 79 | 80 | You can learn more about the @portabletext/to-html package [here](https://github.com/portabletext/to-html) 81 | 82 | ```js 83 | import { portableTextToHtml } from 'astro-sanity'; 84 | import { urlForImage } from './urlForImage'; 85 | 86 | const customComponents = { 87 | /* your custom components here */ 88 | }; 89 | 90 | export function sanityPortableText(portabletext) { 91 | return portableTextToHtml(portabletext, customComponents); 92 | } 93 | ``` 94 | 95 | ### Create a PortableText Astro Component 96 | 97 | ```astro 98 | --- 99 | import { sanityPortableText } from '../sanity/portableText' 100 | 101 | const {portableText} = Astro.props; 102 | --- 103 | 104 | 105 | ``` 106 | 107 | This can then be used in your Astro files and convert portable text to HTML automatically. 108 | 109 | ```astro 110 | 111 | ``` 112 | 113 | ## Support 114 | 115 | Please feel free to reach out to us on our Discord if you have questions or file an issue on the repo. 116 | 117 | [Join Little Sticks Discord](https://littlesticks.dev/discord) 118 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ⚠️ Astro + Sanity Integration 2 | 3 | This plugin has been deprecated. Please refer to [the official Sanity + Astro Plugin](https://www.sanity.io/plugins/sanity-astro) going forward. 4 | 5 | --- 6 | 7 | ## 8 | 9 | This is a helper package for integrating [Sanity](https://www.sanity.io/) with [Astro](https://astro.build/). It is not officially from Sanity but it is architected in the same way their official packages for frameworks like NextJS are. 10 | 11 | ## Installation 12 | 13 | ```bash 14 | npx astro add astro-sanity 15 | ``` 16 | 17 | Follow the prompts and once it's finished you should have something like the following in your `astro.config.mjs` file: 18 | 19 | ```js 20 | import sanity from 'astro-sanity' 21 | 22 | ... 23 | 24 | export default defineConfig({ 25 | integrations: [sanity()], 26 | }); 27 | ``` 28 | 29 | Update the sanity config to match your Sanity Client Config like so: 30 | 31 | ```js 32 | export default defineConfig({ 33 | integrations: [ 34 | sanity({ 35 | projectId: 'YOUR_PROJECT_ID', 36 | dataset: 'production', 37 | apiVersion: '2021-03-25', 38 | useCdn: true, 39 | })], 40 | }); 41 | ``` 42 | 43 | ## Usage 44 | 45 | Please see the [`/demo`](https://github.com/littlesticks/astro-sanity/tree/main/demo) for a full example. However, this package was designed to give you the building blocks to integrate with Sanity but the flexibility to implement it how you want with the helper function names and behavior you want. 46 | 47 | ### Using the Client 48 | 49 | You can globally use the Sanity Client from the config with the following import 50 | 51 | ```js 52 | import { useSanityClient } from 'astro-sanity'; 53 | ``` 54 | 55 | ### Querying Sanity with your Client 56 | 57 | Here is an example using the client to query Sanity: 58 | 59 | ```js 60 | import { useSanityClient, groq } from 'astro-sanity'; 61 | 62 | export async function getFirstBlogPost() { 63 | const query = groq`*[_type == "post"]`; 64 | const firstPost = await useSanityClient().fetch(query); 65 | return firstPost; 66 | } 67 | ``` 68 | 69 | ### Create Your own Image Builder Helper 70 | 71 | You can learn more about Sanity's image builder [here](https://www.sanity.io/docs/image-url). Here is an example of how you can create your own helper function to use in your components: 72 | 73 | ```js 74 | import { useSanityClient } from 'astro-sanity'; 75 | import { createImageBuilder } from 'astro-sanity'; 76 | 77 | export const imageBuilder = createImageBuilder(useSanityClient()); 78 | 79 | export function urlForImage(source) { 80 | return imageBuilder.image(source); 81 | } 82 | ``` 83 | 84 | ### Create a Custom portableTextToHtml Serializer 85 | 86 | You can learn more about the @portabletext/to-html package [here](https://github.com/portabletext/to-html) 87 | 88 | ```js 89 | import { portableTextToHtml } from 'astro-sanity'; 90 | import { urlForImage } from './urlForImage'; 91 | 92 | const customComponents = { 93 | /* your custom components here */ 94 | }; 95 | 96 | export function sanityPortableText(portabletext) { 97 | return portableTextToHtml(portabletext, customComponents); 98 | } 99 | ``` 100 | 101 | ### Create a PortableText Astro Component 102 | 103 | ```astro 104 | --- 105 | import { sanityPortableText } from '../sanity/portableText' 106 | 107 | const {portableText} = Astro.props; 108 | --- 109 | 110 | 111 | ``` 112 | 113 | This can then be used in your Astro files and convert portable text to HTML automatically. 114 | 115 | ```astro 116 | 117 | ``` 118 | 119 | ## Support 120 | 121 | Please feel free to reach out to us on our Discord if you have questions or file an issue on the repo. 122 | 123 | [Join Little Sticks Discord](https://littlesticks.dev/discord) 124 | --------------------------------------------------------------------------------