Skip to content

Commit

Permalink
add Astro + Sanity + Turborepo starter
Browse files Browse the repository at this point in the history
  • Loading branch information
milewskibogumil committed Sep 13, 2024
0 parents commit 30fda0c
Show file tree
Hide file tree
Showing 70 changed files with 1,943 additions and 0 deletions.
25 changes: 25 additions & 0 deletions .github/workflows/sanity-deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: Deploy Sanity Studio
on:
push:
branches: [main]
paths:
- "apps/sanity/**"
jobs:
deploy:
name: Build and Deploy
runs-on: ubuntu-latest
env:
SANITY_AUTH_TOKEN: ${{ secrets.SANITY_DEPLOY_STUDIO_TOKEN }}
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 2
- uses: actions/setup-node@v2
with:
node-version: "18.x"
- uses: oven-sh/setup-bun@v2
- name: Deploy Sanity Studio
run: |
cd ./apps/sanity
bun install
bun run sanity deploy
38 changes: 38 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# Dependencies
node_modules
.pnp
.pnp.js

# Local env files
.env
.env.local
.env.development.local
.env.test.local
.env.production.local

# Testing
coverage

# Turbo
.turbo

# Vercel
.vercel

# Build Outputs
.next/
out/
build
dist


# Debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# Misc
.DS_Store
*.pem
7 changes: 7 additions & 0 deletions .prettierrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"semi": false,
"singleQuote": true,
"trailingComma": "es5",
"tabWidth": 2,
"printWidth": 120
}
75 changes: 75 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# 🚀 Astro + Sanity + Turborepo Starter

⚡️ Kickstart your web projects with the [Astro](https://astro.build/) + [Sanity](https://www.sanity.io/) + [Truborepo](https://turbo.build/) Starter! Integrate Astro, Sanity, and Turborepo for high performance, Core Web Vitals optimization, and SEO-friendly web development. Perfect for building modern, fast, and flexible web applications with ease.

## Features

- **Portable Text**: Flexible rich text handling with customizable structures.
- **Type Safety**: TypeScript support throughout the project.
- **SEO Optimization**: Dynamic metadata fetching and SEO-friendly URLs.
- **Sanity Integration**: Seamless content management with Sanity CMS.
- **Error Handling**: Robust error management in metadata and content fetching.
- **Customizable Components**: Flexibility in rendering text and links.
- **Development Tools**: Integrated ESLint, Prettier, and TypeScript for high code quality.
- **Preview Functionality**: Fast content preview and internal linking within Sanity.
- **Singleton Types & Validation**: Ensures data integrity and easy management of global settings.

## Advantages

- **Performance**: Fast builds and efficient development with Turborepo.
- **Type Safety**: Comprehensive TypeScript integration for reliable code.
- **SEO-Ready**: Built-in optimizations for improved SEO performance.
- **Seamless Integration**: Smooth content management with Sanity.
- **Customizability**: Extensible components and flexible Portable Text configuration.
- **CI/CD**: Automated Sanity deployments with GitHub Actions.

## Setup Instructions

### 1. Environment Variables

Set the following environment variables for local or production setups:

**Sanity Studio Preview**

In the `/apps/sanity` directory, create a `.env.local` file with:

```
SANITY_STUDIO_PREVIEW_DOMAIN=<your_dev_deployment_URL>
```

**Astro API Token**

In the `/apps/astro` directory, create a `.env.local` file with:

```
SANITY_API_TOKEN=<your_sanity_token>
```

_Generate this token in your Sanity project dashboard._

### 2. Constant Files

Update `constants.ts` in both `/apps/sanity/constants.ts` and `/apps/astro/src/global/constants.ts` directories to match your project settings.

### 3. Project ID

Update the `projectId` in:

- `/apps/astro/src/utils/sanity.fetch.ts`
- `/apps/sanity/sanity.cli.ts`
- `/apps/sanity/sanity.config.ts`

_Ensure these IDs correspond to your Sanity project._

### 4. GitHub Actions

To automatically deploy the Sanity Studio:

- **Deployment Trigger**: Automatic deployment occurs when you push changes to any file within the `/apps/sanity/*` directory.
- **Required Environment Variables**:
- `SANITY_DEPLOY_STUDIO_TOKEN`: Add this token to your GitHub project's environment variables for deployment.
- `SANITY_STUDIO_PREVIEW_DOMAIN`: Set this variable for your preview deployment domain in Sanity Studio.

## Authors

- [@milewskibogumil](https://github.com/milewskibogumil)
24 changes: 24 additions & 0 deletions apps/astro/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# build output
dist/
# generated types
.astro/

# dependencies
node_modules/

# logs
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*


# environment variables
.env
.env.production

# macOS-specific files
.DS_Store

# jetbrains setting folder
.idea/
4 changes: 4 additions & 0 deletions apps/astro/.vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"recommendations": ["astro-build.astro-vscode"],
"unwantedRecommendations": []
}
11 changes: 11 additions & 0 deletions apps/astro/.vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"version": "0.2.0",
"configurations": [
{
"command": "./node_modules/.bin/astro dev",
"name": "Development server",
"request": "launch",
"type": "node-terminal"
}
]
}
25 changes: 25 additions & 0 deletions apps/astro/astro.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { defineConfig } from "astro/config";
import vercel from "@astrojs/vercel/serverless";
import sitemap from "@astrojs/sitemap";
import { DOMAIN } from "./src/global/constants";
import { isPreviewDeployment } from "./src/utils/is-preview-deployment";
import redirects from "./redirects";

export default defineConfig({
site: DOMAIN,
integrations: [
sitemap(),
],
image: {
remotePatterns: [{
protocol: "https",
hostname: "cdn.sanity.io"
}],
},
prefetch: {
prefetchAll: true
},
redirects: redirects,
output: isPreviewDeployment ? "server" : 'hybrid',
adapter: vercel(),
});
10 changes: 10 additions & 0 deletions apps/astro/eslint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import eslintPluginAstro from 'eslint-plugin-astro';

export default [
...eslintPluginAstro.configs.recommended,
{
rules: {
"no-unused-vars": "error",
}
}
];
30 changes: 30 additions & 0 deletions apps/astro/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"name": "astro-app",
"type": "module",
"version": "0.0.1",
"private": true,
"scripts": {
"dev": "astro dev",
"start": "astro dev",
"build": "astro check && astro build",
"preview": "astro preview",
"astro": "astro"
},
"dependencies": {
"@astrojs/check": "^0.9.3",
"@astrojs/sitemap": "^3.1.6",
"@astrojs/vercel": "^7.8.1",
"@sanity/client": "^6.21.3",
"astro": "^4.15.5",
"astro-portabletext": "^0.10.0",
"sharp-ico": "^0.1.5",
"typescript": "^5.6.2"
},
"devDependencies": {
"@typescript-eslint/parser": "^8.5.0",
"eslint": "^9.10.0",
"eslint-plugin-astro": "^1.2.4",
"eslint-plugin-jsx-a11y": "^6.10.0",
"sass": "^1.78.0"
}
}
Binary file added apps/astro/public/fonts/Poppins-Regular.eot
Binary file not shown.
Binary file added apps/astro/public/fonts/Poppins-Regular.ttf
Binary file not shown.
Binary file added apps/astro/public/fonts/Poppins-Regular.woff
Binary file not shown.
Binary file added apps/astro/public/fonts/Poppins-Regular.woff2
Binary file not shown.
42 changes: 42 additions & 0 deletions apps/astro/redirects.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import type { ValidRedirectStatus } from "astro";
import { isPreviewDeployment } from "./src/utils/is-preview-deployment";

type RedirectData = {
source: string;
destination: string;
isPermanent: boolean;
};

let redirects = {};

if (isPreviewDeployment) {
console.log('\x1b[33m%s\x1b[0m', "🔀 Redirects are disabled in preview deployments");
} else {
const { default: sanityFetch } = await import("./src/utils/sanity.fetch");
const data = await sanityFetch<RedirectData[]>({
query: `
*[_type == "redirects"][0].redirects {
"source": source.current,
"destination": destination.current,
isPermanent,
}[]
`
});
redirects = Object.fromEntries(
data.map(({ source, destination, isPermanent }) => [
source, {
status: (isPermanent ? 301 : 302) as ValidRedirectStatus,
destination
}
])
);

const permanentRedirects = data.filter(r => r.isPermanent).length;
const temporaryRedirects = data.length - permanentRedirects;
console.log(
'\x1b[32m%s\x1b[0m',
`✅ \x1b[1m${Object.keys(redirects).length}\x1b[0m\x1b[32m redirects added from Sanity (\x1b[1m${permanentRedirects}\x1b[0m\x1b[32m permanent and \x1b[1m${temporaryRedirects}\x1b[0m\x1b[32m temporary)`
);
}

export default redirects;
1 change: 1 addition & 0 deletions apps/astro/src/assets/favicon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added apps/astro/src/assets/icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions apps/astro/src/components/ui/PortableText/Block.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<slot />
14 changes: 14 additions & 0 deletions apps/astro/src/components/ui/PortableText/Cmp.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
import { PortableText } from 'astro-portabletext'
import type { PortableTextValue } from '.'
import Block from './Block.astro'
import Mark from './Mark.astro'
type Props = {
value: PortableTextValue
}
const { value } = Astro.props
---

<PortableText value={value} components={{ block: Block, mark: Mark }} />
21 changes: 21 additions & 0 deletions apps/astro/src/components/ui/PortableText/Mark.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
---
import type { Props as $, Mark as MarkType } from 'astro-portabletext/types'
import { Mark as PortableTextMark } from 'astro-portabletext/components'
export type Props = $<MarkType<never>>
const { node, ...props } = Astro.props
const { href, type } = node.markDef as { href: string; type: 'external' | 'internal' }
const isExternal = type === 'external'
---

{
node.markType === 'link' ? (
<a href={href} {...(isExternal && { target: '_blank', rel: 'noreferrer' })} {...props}>
<slot />
</a>
) : (
PortableTextMark
)
}
28 changes: 28 additions & 0 deletions apps/astro/src/components/ui/PortableText/index.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
---
import type { HTMLAttributes } from 'astro/types'
import type { PortableTextProps } from 'astro-portabletext/types'
import Cmp from './Cmp.astro'
export type PortableTextValue = PortableTextProps['value']
type Props = {
value: PortableTextValue
heading?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6'
} & HTMLAttributes<'div' | 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6'>
const { heading: HeadingTag, value, ...props } = Astro.props
const valueArray = Array.isArray(value) ? value : [value]
---

{
HeadingTag ? (
<HeadingTag {...props}>
{valueArray.map((value: PortableTextValue, index: number) =>
index > 0 ? <span {...props}>{<Cmp value={value} />}</span> : <Cmp value={value} />
)}
</HeadingTag>
) : (
<Cmp value={value} />
)
}
15 changes: 15 additions & 0 deletions apps/astro/src/components/ui/PortableText/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
export { default, type PortableTextValue } from './index.astro';

export const PortableTextQuery = (name: string) => `
${name}[] {
...,
markDefs[] {
_type == "link" => {
_type,
_key,
type,
"href": select(type == "internal" => internal -> slug.current, type == "external" => external, "#"),
},
},
},
`
Loading

0 comments on commit 30fda0c

Please sign in to comment.