npm create astro@latest -- --template minimal
🧑🚀 Seasoned astronaut? Delete this file. Have fun!
Inside of your Astro project, you'll see the following folders and files:
/
├── public/
├── src/
│ └── pages/
│ └── index.astro
└── package.json
Astro looks for .astro
or .md
files in the src/pages/
directory. Each page is exposed as a route based on its file name.
There's nothing special about src/components/
, but that's where we like to put any Astro/React/Vue/Svelte/Preact components.
Any static assets, like images, can be placed in the public/
directory.
All commands are run from the root of the project, from a terminal:
Command | Action |
---|---|
npm install |
Installs dependencies |
npm install -D @playwright/test@latest |
Install Playwrite |
npx playwright install --with-deps |
Install dependencies |
npm run build -mode production |
build and use playwrite when required. |
npm run dev |
Starts local dev server at localhost:4321 |
npm run build |
Build your production site to ./dist/ |
npm run preview |
Preview your build locally, before deploying |
npm run astro ... |
Run CLI commands like astro add , astro check |
npm run astro -- --help |
Get help using the Astro CLI |
Setup environment variable. Assumes that Wrangler CLI has been installed and permissions granted.
$ENV:CLOUDFLARE_ACCOUNT_ID = "XXXXXXXXXXXXXXXXX"
From the directory root use the following to deploy.
npx wrangler pages deploy dist --project-name=astro-throughputfocus-com
When you have got the functions working, commit to github and github action will commit the saved changes.
Feel free to check our documentation or jump into our Discord server.
Sizable images from https://picsum.photos/
Title: Up to 150 characters. Image: The image gets cropped into a 1.91:1 ratio and 1200 (width) x 627 (height) pixels. So you need an image with a compatible ratio and width of 1200px+. Optional comment of up to 1300 characters. (This is the LinkedIn post that you write outside of the link.)
Use the LinkedIn Debugger to preview. https://kinsta.com/blog/linkedin-debugger/
How to use Github action to convert plant uml digrams to SVG files https://gist.github.com/thedmeyer/8b50362ae71ecbadabb17f8683c70ece
Error: Cannot find module @rollup/rollup-linux-x64-gnu. npm has a bug related to optional dependencies (npm/cli#4828). Please try npm i
again after removing both package-lock.json and node_modules directory.
see if you can use another package manager.
Rebuild site with Astro.
https://developers.cloudflare.com/pages/platform/functions/
https://eben.gilkenson.com/code/cloudflare-workers/cloudflare-worker-contact-form/ Basic Contact Form with Cloudflare Workers Published on February 23rd, 2022 A contact form just needs to take form data and get it to whoever needs it. For the small sites that I work on, this has been done so easily for years with the PHP mail() function. Moving to a serverless platform becomes somewhat more involved, but provides opportunities to add features that would be harder to implement with a PHP script.
https://medium.com/whitespectre/ultrafast-serverless-sites-our-cloudflare-pages-prototype-ecc6632b9472 Ultrafast serverless sites: Our Cloudflare Pages Prototype Test driving Cloudflare’s ambitious platform-as-a-service solution by creating a JAMstack-like application with their new Pages product.
https://noise.getoto.net/tag/serverless-functions/
https://blog.cloudflare.com/building-full-stack-with-pages/
https://discord.com/channels/595317990191398933/789155108529111069/962574142417272862 Providing an update on this so it may help others. If you want a custom domain pointing to a preview branch AND cloudflare access on top of it, you need to make sure you have two applications on cloudflare access: one for *.<pages_app>.pages.dev and another for your custom domain (e.g. preview.example.com). I set up the same policies for both. With that, you can now access preview deployments through preview.example.com, get prompted for auth from cloudflare access, and after you auth you'll see your preview pages app. Without the extra cloudflare access rule for preview.example.com you'll get stuck on an intermediary page after the cloudflare access auth page, and nothing you do will let you see your preview pages app through the custom domain.
setup a custom domain pointing at a preview branch
https://discord.com/channels/595317990191398933/789155108529111069/933334599935885322 Each branch has an alias domain like qa.project.pages.dev
To link these to custom domains, first add the domains as custom domains (So add qa.example.com to the custom domains area on the project), then once its all processed go to the DNS for that domain and change the created cname to be the branch alias like qa.project.pages.dev. Repeat for all other domains accordingly.
It's important that you add all the domains to the Custom Domains area first, or they won't route to the project anymore. The DNS change simply changes which branch they should use
https://discord.com/channels/595317990191398933/789155108529111069/933503057570955335 added a _headers file to the output folder Check the settings with https://securityheaders.com/ or https://csp-evaluator.withgoogle.com/
How to get the markdown source for pages
const pages = await Astro.glob("../../content/pages/*.md");
const rawPages = await Promise.all( pages.map(async (page) => await page.default().metadata.source) );
// An astro .md markdown file layout: ../layouts/Photo.astro title: Photos description: A Photo of something! publishDate: 2019-12-14T09:00:00-08:00 setup: | import { Picture } from "astro-imagetools/components";
<Picture src="https://picsum.photos/1600/900" alt="A random image" format={["avif", "webp", "png"]} breakpoints={[200, 400, 800, 1600]} />
<Picture src="https://picsum.photos/1024/768" alt="A random image" format={["avif", "webp", "png"]} breakpoints={{count: 3, minWidth: 300, maxWidth: 1024}} />
{openGraph &&
<meta property="og:title" content=${openGraph.basic.title} /> <meta property="og:type" content=${openGraph.basic.type} /> <meta property="og:image" content=${openGraph.basic.image} /> <meta property="og:url" content=${openGraph.basic.url} />
}
https://www.bannerbear.com/tools/twitter-card-preview-tool/
https://www.linkedin.com/post-inspector/
https://detailed.com/extension/
For astro pages and md pages
https://codesandbox.io/s/upbeat-http-k8ifvm?file=/src/pages/index.astro:295-323
https://github.com/astro-community/astro-embed/blob/main/packages/astro-embed/README.md
'''
'''Markdown pages
You can also import an embed component for use on a Markdown page.
'''
setup: | import { Tweet, YouTube } from 'astro-embed';
Hey look! I can embed a tweet in Markdown!
YouTube videos work too :-)
'''You can do that using the attributes prop, attributes={{ img: { class: "custom-class" } }}
Not possible yet! See withastro/astro#3203
// src/components/GlobPosts.js
let allPosts = import.meta.globEager('@pages/posts/*.md') allPosts = allPosts.sort((a, b) => new Date(b.date).valueOf() - new Date(a.date).valueOf()); allPosts = import.meta.env.DEV ? allPosts : allPosts.filter((a)=>!a.draft);
export {allPosts};
See https://www.readonlychild.com/blog/astro-md-content/
// src/pages/rss.xml.js import rss from '@astrojs/rss'; const postImportResult = import.meta.globEager('../posts/*/.md'); const posts = Object.values(postImportResult); export const get = () => rss({ title: 'Buzz’s Blog', description: 'A humble Astronaut’s guide to the stars', items: posts.map((post) => ({ link: post.frontmatter.slug, title: post.frontmatter.title, pubDate: post.frontmatter.pubDate, })) });
See https://github.com/withastro/docs/pull/430/files
URL interface from Astro.request.url to use it in the way you used to:
const pathname = new URL(Astro.request.url).pathname;
==================
// help.astro const mode = import.meta.env.MODE; ...
Seems like it needs a rag around condition. {item.original_language === 'en' ? item.title : item.original_language}
Here’s the basic tsconfig all of Astro’s starters come with:
{ "compilerOptions": { // Enable top-level await, and other modern ESM features. "target": "ESNext", "module": "ESNext", // Enable node-style module resolution, for things like npm package imports. "moduleResolution": "node", // Enable JSON imports. "resolveJsonModule": true, // Enable stricter transpilation for better output. "isolatedModules": true, // Add type definitions for our Vite runtime. "types": ["vite/client"] } }
https://discord.com/channels/830184174198718474/845451724738265138/973596845764919327
Sample from Movies endpoint:
[
{
title: 'Fast Color',
genre_ids: [ 53, 878 ],
},
]
Sample from Genres endpoint: [ { id: 28, name: 'Action' }, { id: 12, name: 'Adventure' }, ]
Abbreviated JS thus far:
const loadGenres = async () => { const response = await fetch(genres_url); const results = await response.json(); return results.genres; };
const loadMovies = async () => { const response = await fetch(movies_url); const results = await response.json(); return results.results; };
const genres = await loadGenres(); const movies = await loadMovies();
Autothreader BOT — Yesterday at 3:46 PM Hey @djmtype! I've automatically created this helpful thread from your message 17 hours ago.
Pinging @support-squad so that they see this as well! [3:46 PM] Done with your thread? Press Resolve Thread to auto-archive the discussion for everyone.
Resolve Thread [3:46 PM] You can also right-click the thread in Discord (or use the ... menu) and select Leave Thread to unsubscribe from future updates.
readonlychild (ernesto) — Yesterday at 3:55 PM pseudo-code [3:55 PM] function getGenreById (id, genres) { let g = '??'; genres.forEach((genre) => { if (genre.id === id) g = genre.name; } return g; }
Genre 28 = {getGenreById(28, genres)}
https://discord.com/channels/830184174198718474/845451724738265138/973718140859076638
I'm trying to fetch more details about each movie so I'm making 2 fetch calls.
async function loadMovies() {
const entries = [];
let page = 1;
const allMovies = https://api.themoviedb.org/3/account/xxx/favorite/movies?xxx&page=${page}
;
let data = await fetch(allMovies);
let fetchResults = await data.json();
entries.push(...fetchResults.results);
const allSingleMovies = []
for (const item of entries) {
const singleMovie = `https://api.themoviedb.org/3/movie/${item.id}?xxx`;
const data = await fetch(singleMovie);
let singleMovieResults = await data.json();
allSingleMovies.push(singleMovieResults);
}
return allSingleMovies;
}
let movies = await loadMovies();
-
{movies.map((item) =>
- {item.title} )}
In your terminal you just run DEBUG="astro:build" npm run build
or in MS-Windows at Powershell prompt $env:DEBUG='astro:build'; & npm run build
---
const condition = true;
---
{
() => {
const img = <img src="https://picsum.photos/1024/768" alt="" />;
return condition ? <div>{img}</div> : img;
}
}
const DATABASE_URL = process.env.DATABASE_URL || import.meta.env.DATABASE_URL;
or create helper utility
export function getEnvVar(name) { return process.env[name] || import.meta.env[name]; }
import { Button } from '../components';
function handlePie() { const response = await fetch('/api/pie?flavor=cherry'); const pie = await response.json(); alert(pie); }
Test '''
/api/pie.js: ''' export async function get ({ request }) { let response, status; const parsedURL = new URL(request.url); const flavor = parsedURL.searchParams.get('flavor'); if (flavor) { response = { flavor }; status = 200; }
if (!flavor) { response = { message: 'Flavor not found' }; status = 404; }
return new Response(JSON.stringify(response, null, 2), { status, headers: { 'Content-Type': 'application/json' } }); } '''
vercel/vercel#5204 Can take any JSON POST body and we turn that into a log event. Nested, not nested, anything.