diff options
Diffstat (limited to 'docs/src/pages/reference')
-rw-r--r-- | docs/src/pages/reference/api-reference.md | 179 | ||||
-rw-r--r-- | docs/src/pages/reference/builtin-components.md | 32 | ||||
-rw-r--r-- | docs/src/pages/reference/cli-reference.md | 58 | ||||
-rw-r--r-- | docs/src/pages/reference/configuration-reference.md | 30 | ||||
-rw-r--r-- | docs/src/pages/reference/renderer-reference.md | 158 |
5 files changed, 457 insertions, 0 deletions
diff --git a/docs/src/pages/reference/api-reference.md b/docs/src/pages/reference/api-reference.md new file mode 100644 index 000000000..834ab92c3 --- /dev/null +++ b/docs/src/pages/reference/api-reference.md @@ -0,0 +1,179 @@ +--- +layout: ~/layouts/Main.astro +title: API Reference +--- + +## `Astro` global + +The `Astro` global is available in all contexts in `.astro` files. It has the following functions: + +### `Astro.fetchContent()` + +`Astro.fetchContent()` is a way to load local `*.md` files into your static site setup. You can either use this on its own, or within [Astro Collections](/core-concepts/collections). + +```jsx +// ./src/components/my-component.astro +--- +const data = Astro.fetchContent('../pages/post/*.md'); // returns an array of posts that live at ./src/pages/post/*.md +--- + +<div> +{data.slice(0, 3).map((post) => ( + <article> + <h1>{post.title}</h1> + <p>{post.description}</p> + <a href={post.url}>Read more</a> + </article> +))} +</div> +``` + +`.fetchContent()` only takes one parameter: a relative URL glob of which local files you’d like to import. Currently only `*.md` files are supported. It’s synchronous, and returns an array of items of type: + +```js +{ + /** frontmatter from the post.. example frontmatter: + title: '', + tag: '', + date: '', + image: '', + author: '', + description: '', + **/ + astro: { + headers: [], // an array of h1...h6 elements in the markdown file + source: '' // raw source of the markdown file + html: '' // rendered HTML of the markdown file + }, + url: '' // the rendered path + }[] +``` + +### `Astro.request` + +`Astro.request` returns an object with the following properties: + +| Name | Type | Description | +| :------------- | :---- | :---------------------------------------------- | +| `url` | `URL` | The URL of the request being rendered. | +| `canonicalURL` | `URL` | [Canonical URL][canonical] of the current page. | + +⚠️ Temporary restriction: this is only accessible in top-level pages and not in sub-components. + +### `Astro.site` + +`Astro.site` returns a `URL` made from `buildOptions.site` in your Astro config. If undefined, this will return a URL generated from `localhost`. + +## Collections API +### `collection` prop + +```jsx +const { collection } = Astro.props; +``` + +When using the [Collections API](/core-concepts/collections), `collection` is a prop exposed to the page with the following shape: + +| Name | Type | Description | +| :------------------------ | :-------------------: | :-------------------------------------------------------------------------------------------------------------------------------- | +| `collection.data` | `Array` | Array of data returned from `data()` for the current page. | +| `collection.start` | `number` | Index of first item on current page, starting at `0` (e.g. if `pageSize: 25`, this would be `0` on page 1, `25` on page 2, etc.). | +| `collection.end` | `number` | Index of last item on current page. | +| `collection.total` | `number` | The total number of items across all pages. | +| `collection.page.current` | `number` | The current page number, starting with `1`. | +| `collection.page.size` | `number` | How many items per-page. | +| `collection.page.last` | `number` | The total number of pages. | +| `collection.url.current` | `string` | Get the URL of the current page (useful for canonical URLs) | +| `collection.url.prev` | `string \| undefined` | Get the URL of the previous page (will be `undefined` if on page 1). | +| `collection.url.next` | `string \| undefined` | Get the URL of the next page (will be `undefined` if no more pages). | +| `collection.params` | `object` | If page params were used, this returns a `{ key: value }` object of all values. | + +### `createCollection()` + +```jsx +export async function createCollection() { + return { + async data({ params }) { + // load data + }, + pageSize: 25, + routes: [{ tag: 'movie' }, { tag: 'television' }], + permalink: ({ params }) => `/tag/${params.tag}`, + }; +} +``` + +When using the [Collections API](/core-concepts/collections), `createCollection()` is an async function that returns an object of the following shape: + +| Name | Type | Description | +| :---------- | :--------------------------------------: | :--------------------------------------------------------------------------------------------------------- | +| `data` | `async ({ params }) => any[]` | **Required.** Load an array of data with this function to be returned. | +| `pageSize` | `number` | Specify number of items per page (default: `25`). | +| `routes` | `params[]` | **Required for URL Params.** Return an array of all possible URL `param` values in `{ name: value }` form. | +| `permalink` | `({ params }) => string` | **Required for URL Params.** Given a `param` object of `{ name: value }`, generate the final URL.\* | +| `rss` | [RSS](/reference/api-reference#rss-feed) | Optional: generate an RSS 2.0 feed from this collection ([docs](/reference/api-reference#rss-feed)) | + +_\* Note: don’t create confusing URLs with `permalink`, e.g. rearranging params conditionally based on their values._ + +⚠️ `createCollection()` executes in its own isolated scope before page loads. Therefore you can’t reference anything from its parent scope. If you need to load data you may fetch or use async `import()`s within the function body for anything you need (that’s why it’s `async`—to give you this ability). If it wasn’t isolated, then `collection` would be undefined! Therefore, duplicating imports between `createCollection()` and your Astro component is OK. + +#### RSS Feed + +You can optionally generate an RSS 2.0 feed from `createCollection()` by adding an `rss` option. Here are all the options: + +```jsx +export async function createCollection() { + return { + async data({ params }) { + // load data + }, + pageSize: 25, + rss: { + title: 'My RSS Feed', + description: 'Description of the feed', + /** (optional) add xmlns:* properties to root element */ + xmlns: { + itunes: 'http://www.itunes.com/dtds/podcast-1.0.dtd', + content: 'http://purl.org/rss/1.0/modules/content/', + }, + /** (optional) add arbitrary XML to <channel> */ + customData: `<language>en-us</language> +<itunes:author>The Sunset Explorers</itunes:author>`, + /** Format each item from things returned in data() */ + item: (item) => ({ + title: item.title, + description: item.description, + pubDate: item.pubDate + 'Z', // enforce GMT timezone (otherwise it’ll be different based on where it’s built) + /** (optional) add arbitrary XML to each <item> */ + customData: `<itunes:episodeType>${item.type}</itunes:episodeType> +<itunes:duration>${item.duration}</itunes:duration> +<itunes:explicit>${item.explicit || false}</itunes:explicit>`, + }), + }, + }; +} +``` + +Astro will generate an RSS 2.0 feed at `/feed/[collection].xml` (for example, `/src/pages/$podcast.xml` would generate `/feed/podcast.xml`). + +⚠️ Even though Astro will create the RSS feed for you, you’ll still need to add `<link>` tags manually in your `<head>` HTML: + +```html +<link rel="alternate" type="application/rss+xml" title="My RSS Feed" href="/feed/podcast.xml" /> +``` + +## `import.meta` + +All ESM modules include a `import.meta` property. Astro adds `import.meta.env` through [Snowpack](https://www.snowpack.dev/). + +**import.meta.env.SSR** can be used to know when rendering on the server. Some times you might want different logic, for example a component that should only be rendered in the client: + +```jsx +import { h } from 'preact'; + +export default function () { + return import.meta.env.SSR ? <div class="spinner"></div> : <FancyComponent />; +} +``` + +[canonical]: https://en.wikipedia.org/wiki/Canonical_link_element + diff --git a/docs/src/pages/reference/builtin-components.md b/docs/src/pages/reference/builtin-components.md new file mode 100644 index 000000000..109a5cba0 --- /dev/null +++ b/docs/src/pages/reference/builtin-components.md @@ -0,0 +1,32 @@ +--- +layout: ~/layouts/Main.astro +title: Built-In Components +--- + +Astro includes several builtin components for you to use in your projects. All builtin components are available via `import {} from 'astro/components';`. + +## `<Markdown />` + +```astro +--- +import { Markdown } from 'astro/components'; +--- +<Markdown> + # Markdown syntax is now supported! **Yay!** +</Markdown> +``` + +See our [Markdown Guide](/guides/markdown-content) for more info. +<!-- TODO: We should move some of the specific component info here. --> + + +## `<Prism />` + +```astro +--- +import { Prism } from 'astro/components'; +--- +<Prism code={`const foo = 'bar';`} /> +``` + +This component provides syntax highlighting for code blocks. Since this never changes in the client it makes sense to use an Astro component (it's equally reasonable to use a framework component for this kind of thing; Astro is server-only by default for all frameworks!). diff --git a/docs/src/pages/reference/cli-reference.md b/docs/src/pages/reference/cli-reference.md new file mode 100644 index 000000000..410758c09 --- /dev/null +++ b/docs/src/pages/reference/cli-reference.md @@ -0,0 +1,58 @@ +--- +layout: ~/layouts/Main.astro +title: CLI Reference +--- + +## Commands + +### `astro dev` + +Runs the Astro development server. This starts an HTTP server that responds to requests for pages stored in `src/pages` (or which folder is specified in your [configuration](/reference/configuration-reference)). + +See the [dev server](/reference/dev) docs for more information on how the dev server works. + +**Flags** + +#### `--port` + +Specifies should port to run on. Defaults to `3000`. + +### `astro build` + +Builds your site for production. + +## Global Flags + +### `--config path` + +Specify the path to the config file. Defaults to `astro.config.mjs`. Use this if you use a different name for your configuration file or have your config file in another folder. + +```shell +astro --config config/astro.config.mjs dev +``` + +### `--project-root path` + +Specify the path to the project root. If not specified the current working directory is assumed to be the root. + +The root is used for finding the Astro configuration file. + +```shell +astro --project-root examples/snowpack dev +``` + +### `--reload` + +Clears the cache (dependencies are built within Astro apps). + +### `--verbose` + +Enables verbose logging, which is helpful when debugging an issue. + +### `--version` + +Print the Astro version number and exit. + +### `--help` + +Print the help message and exit. diff --git a/docs/src/pages/reference/configuration-reference.md b/docs/src/pages/reference/configuration-reference.md new file mode 100644 index 000000000..055024ca8 --- /dev/null +++ b/docs/src/pages/reference/configuration-reference.md @@ -0,0 +1,30 @@ +--- +layout: ~/layouts/Main.astro +title: Configuration Reference +--- + +To configure Astro, add an `astro.config.mjs` file in the root of your project. All settings are optional. Here are the defaults: + +```js +export default { + projectRoot: '.', // Where to resolve all URLs relative to. Useful if you have a monorepo project. + src: './src', // Path to Astro components, pages, and data + pages: './src/pages', // Path to Astro/Markdown pages + dist: './dist', // When running `astro build`, path to final static output + public: './public', // A folder of static files Astro will copy to the root. Useful for favicons, images, and other files that don’t need processing. + buildOptions: { + // site: '', // Your public domain, e.g.: https://my-site.dev/. Used to generate sitemaps and canonical URLs. + sitemap: true, // Generate sitemap (set to "false" to disable) + }, + devOptions: { + port: 3000, // The port to run the dev server on. + // tailwindConfig: '', // Path to tailwind.config.js if used, e.g. './tailwind.config.js' + }, + // component renderers which are enabled by default + renderers: ['@astrojs/renderer-svelte', '@astrojs/renderer-vue', '@astrojs/renderer-react', '@astrojs/renderer-preact'], +}; +``` + +## Snowpack Config + +Astro is powered internally by Snowpack. You can configure Snowpack directly by creating a `snowpack.config.js` file. See [snowpack.dev](https://www.snowpack.dev/reference/configuration) for full documentation on this file.
\ No newline at end of file diff --git a/docs/src/pages/reference/renderer-reference.md b/docs/src/pages/reference/renderer-reference.md new file mode 100644 index 000000000..37e5dd4e7 --- /dev/null +++ b/docs/src/pages/reference/renderer-reference.md @@ -0,0 +1,158 @@ +--- +layout: ~/layouts/Main.astro +title: UI Renderer Reference +--- + +Astro is designed to support your favorite UI frameworks. [React](https://npm.im/@astrojs/renderer-react), [Svelte](https://npm.im/@astrojs/renderer-svelte), [Vue](https://npm.im/@astrojs/renderer-vue), and [Preact](https://npm.im/@astrojs/renderer-preact) are all built-in to Astro and supported out of the box. No configuration is needed to enable these. + +Internally, each framework is supported via a framework **renderer.** A renderer is a type of Astro plugin that adds support for a framework. Some are built-in, but you can also provide your own third-party renderers to add Astro support for new frameworks. + +## What is a renderer? + +A renderer is an NPM package that has two responsiblities: + +1. _render a component to a static string of HTML_ at build time +2. _rehydrate that HTML to create an interactive component_ on the client. + +Take a look at any one of Astro's built-in [`renderers`](https://github.com/snowpackjs/astro/tree/main/packages/renderers) to see this in action. We'll go into more detail in the following sections. + +## Building Your Own Renderer + +> **Building a renderer?** We'd love for you to contribute renderers for popular frameworks back to the Astro repo. Feel free to open an issue or pull request to discuss. + +A simple renderer only needs a few files: + +``` +/my-custom-renderer/ +├── package.json +├── index.js +├── server.js +└── client.js +``` + +### Package Manifest (`package.json`) + +A renderer should include any framework dependencies as package dependencies. For example, `@astrojs/renderer-react` includes `react` & `react-dom` as dependencies in the `package.json` manifest. + +```js +// package.json +"name": "@astrojs/renderer-react", +"dependencies": { + "react": "^17.0.0", + "react-dom": "^17.0.0" +} +``` + +This means that Astro users don't need to install the UI framework packages themselves. The renderer is the only package that your users will need to install. + +### Renderer Entrypoint (`index.js`) + +The main entrypoint of a renderer is a simple JS file which exports a manifest for the renderer. The required values are `name`, `server`, and `client`. + +Additionally, this entrypoint can define a [Snowpack plugin](https://www.snowpack.dev/guides/plugins) that should be used to load non-JavaScript files. + +```js +export default { + name: '@astrojs/renderer-xxx', // the renderer name + client: './client.js', // relative path to the client entrypoint + server: './server.js', // optional, relative path to the server entrypoint + snowpackPlugin: '@snowpack/plugin-xxx', // optional, the name of a snowpack plugin to inject + snowpackPluginOptions: { example: true }, // optional, any options to be forwarded to the snowpack plugin + knownEntrypoint: ['framework'], // optional, entrypoint modules that will be used by compiled source + external: ['dep'] // optional, dependencies that should not be built by snowpack + polyfills: ['./shadow-dom-polyfill.js'] // optional, module scripts that should be loaded before client hydration. + hydrationPolyfills: ['./hydrate-framework.js'] // optional, polyfills that need to run before hydration ever occurs. +}; +``` + +### Server Entrypoint (`server.js`) + +The server entrypoint of a renderer is responsible for checking if a component should use this renderer, and if so, how that component should be rendered to a string of static HTML. + +```js +export default { + // should Component use this renderer? + check(Component, props, childHTML) {}, + // Component => string of static HTML + renderToStaticMarkup(Component, props, childHTML) {}, +}; +``` + +#### `check` + +`check` is a function that determines whether a Component should be "claimed" by this renderer. + +In it's simplest form, it can check for the existence of a flag on Object-based components. + +```js +function check(Component) { + return Component.isMyFrameworkComponent; +} +``` + +In more complex scenarios, like when a Component is a `Function` without any flags, you may need to use `try/catch` to attempt a full render. This result is cached so that it only runs once per-component. + +```js +function check(Component, props, childHTML) { + try { + const { html } = renderToStaticMarkup(Component, props, childHTML); + return Boolean(html); + } catch (e) {} + return false; +} +``` + +#### `renderToStaticMarkup` + +`renderToStaticMarkup` is a function that renders a Component to a static string of HTML. There's usually a method exported by frameworks named something like `renderToString`. + +```js +import { renderToString } from 'xxx'; + +function renderToStaticMarkup(Component, props, childHTML) { + const html = renderToString(h(Component, { ...props, innerHTML: childHTML })); + return { html }; +} +``` + +Note that `childHTML` is an HTML string representing this component's children. If your framework does not support rendering HTML directly, you are welcome to use a wrapper component. By convention, Astro uses the `astro-fragment` custom element to inject `childHTML` into. Your renderer should use that, too. + +```js +import { h, renderToString } from 'xxx'; + +const Wrapper = ({ value }) => h('astro-fragment', { dangerouslySetInnerHTML: { __html: value } }); + +function renderToStaticMarkup(Component, props, childHTML) { + const html = renderToString(h(Component, props, h(Wrapper, { value: childHTML }))); + return { html }; +} +``` + +### Client Entrypoint (`client.js`) + +The client entrypoint of a renderer is responsible for rehydrating static HTML (the result of `renderToStaticMarkup`) back into a fully interactive component. Its `default` export should be a `function` which accepts the host element of the Component, an `astro-root` custom element. + +> If your framework supports non-destructive component hydration (as opposed to a destructive `render` method), be sure to use that! Following your framework's Server Side Rendering (SSR) guide should point you in the right direction. + +```js +import { hydrate } from 'xxx'; + +export default (element) => { + return (Component, props, childHTML) => { + hydrate(h(Component, { ...props, innerHTML: childHTML }), element); + }; +}; +``` + +Note that `childHTML` is an HTML string representing this component's children. If your framework does not support rendering HTML directly, you should use the same wrapper component you used for the server entrypoint. + +```js +import { h, hydrate } from 'xxx'; +import SharedWrapper from './SharedWrapper.js'; + +export default (element) => { + return (Component, props, childHTML) => { + hydrate(h(Component, props, h(SharedWrapper, { value: childHTML })), element); + }; +}; +``` |