parent
d07f3d4186
commit
d40edb0b67
28 changed files with 436 additions and 782 deletions
|
@ -1,241 +0,0 @@
|
|||
---
|
||||
layout: ~/layouts/Main.astro
|
||||
title: Island Architecture
|
||||
draft: true
|
||||
---
|
||||
|
||||
<!--
|
||||
@aFuzzyBear: I have been spending most the day learning more about Island Architecture, wrote plenty of notes, listened to Fred K Schott's interview on Speakeasy(https://www.youtube.com/watch?v=mgkwZqVkrwo) and the interview with Jason Lengstrof (https://www.youtube.com/watch?v=z15YLsLMtu4)
|
||||
Figured I might give writing this a wee go,
|
||||
|
||||
I wanted to take this from the direction of it being more of a critique of the past and present state of affairs in web dev
|
||||
Post structure:
|
||||
1)Start with an introduction to Islands Arch
|
||||
2)Talk about the different Architectures that can be used in Web-dev
|
||||
3)MVC/StaticSites - SPA's
|
||||
4)Frameworks, get some external links onto the page
|
||||
4)Moving to ESM
|
||||
5)Benefits of ESM
|
||||
6)
|
||||
|
||||
-->
|
||||
|
||||
<!-- Intro -->
|
||||
|
||||
> "No man is an island. However, Web Components should be"
|
||||
|
||||
The concept behind Island architecture comes from [Jason Miller](https://twitter.com/_developit), The creator of [Preact](https://preactjs.com/) and a Google, DevRel Engineer.
|
||||
|
||||
In the summer of 2020, he managed to formulated his thoughts of how web architecture should be, in the idyllic sense, and placed them onto his [blog post](https://jasonformat.com/islands-architecture/).
|
||||
|
||||
His seminal post outlines and discusses the general concept of 'islands' as an architectural design process that could be used in Web Development, allowing for better improvements in overall site performance, SEO, UX, and everywhere else. His given explanation describing this new paradigm, was extraordinarily succinct:
|
||||
|
||||
> "The general idea of an _“Islands”_ architecture is deceptively simple: Render HTML pages on the server, and inject placeholders or slots around highly dynamic regions. These placeholders/slots contain the server-rendered HTML output from their corresponding widget. They denote regions that can then be "hydrated" on the client into small self-contained widgets, reusing their server-rendered initial HTML."-Jason Miller
|
||||
|
||||
To develop a better understanding of what Jason meant with his proposal, let's quickly explore the backdrop, before we explain 'Island Architecture' and how it is applied into Astro as our primary ethos.
|
||||
|
||||
## Programming Paradigms
|
||||
|
||||
Think of a simple webpage. On which are many different types of components that are shown on this page, components that are shared across the site, others contain fixed content, some are a bit more elaborate that may perhaps use different state's or need to fetch multiple data streams from external sources.
|
||||
|
||||
Such an site would would have very few actual 'moving' pieces, or _dynamic_ elements. For the most part the content tends to be fixed, and static.
|
||||
|
||||
In order to allow for dynamism and interactivity we are often left making overly complex solutions to deliver the slightest form of action on the application.
|
||||
|
||||
Complexity becomes inherent in the design process of the application. As a result, developers have to adopt some dogma, that comes from certain architectural design styles and patterns.
|
||||
|
||||
Given the [catalogue of patterns](https://en.wikipedia.org/wiki/List_of_software_architecture_styles_and_patterns) that are available, utilizing the right architecture for the application often comes from hard-to-obtain experience.
|
||||
|
||||
Web developers tend to gravitate towards tried and tested practices, and none fit the requirements better than the [Model-View-Controller](https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller) (**MVC**) design pattern.
|
||||
|
||||
Where the **Model** contains the data structures and logic that governs the use of the data in the application. **Views** are the visual representation of the data that the user sees, and the **Controller** connects the views to their relevant data _Models_ based on their interactions with the User.
|
||||
|
||||
This design pattern works well for our [client-server](https://en.wikipedia.org/wiki/Client%E2%80%93server_model) based applications. Since the models are placed on the _servers_, the views that are sent back over the wire tend to be static _documents_, controllers are sent along with the static files to facilitate the behaviours that web developers created for their application, in the form of _scripts_.
|
||||
|
||||
## Rise of the Frameworks
|
||||
|
||||
A vast swathe of libraries, frameworks and tooling rose up to meet the challenges of providing a Developer Experience (DX) that would let them create their applications, _'freely'_.
|
||||
|
||||
Helping to abstract away much of the complexity needed in implementing architectural design decisions into their application.
|
||||
|
||||
The likes of; [ASP.NET](https://dotnet.microsoft.com/learn/aspnet/what-is-aspnet-core) and [Blazor](https://dotnet.microsoft.com/apps/aspnet/web-apps/blazor) for [.NET](https://dotnet.microsoft.com/), [Ruby On Rails](https://rubyonrails.org/), [Laravel](https://laravel.com/) & [Symphony](https://symfony.com/) for [PHP](https://www.php.net/), are examples of the MVC patterns seen in other server-side programming languages.
|
||||
|
||||
For along time, JavaScript was solely restricted to the Browser, then [Node.js](https://nodejs.org/en/) appeared. Node.js is a standalone JavaScript runtime built on the Chrome V8 engine.
|
||||
|
||||
This was a seismic shift that occurred in Web Development, by allowing JavaScript to escape the browser and operate on the server, developers could use JS on both; Front & Back-ends, when developing their applications.
|
||||
|
||||
Within the new JavaScript + Node ecosystem, JS MVC frameworks began to appear, e.g: [BackboneJS](https://backbonejs.org/), [ExpressJS](https://expressjs.com/), [Ember](https://emberjs.com/), [MeteorJS](https://www.meteor.com/), to name but a few.
|
||||
|
||||
This pattern of statically generated content on the server was becoming a bit of a performance bottleneck.
|
||||
|
||||
Where some asset-heavy page would take longer to render on the server than a lighter page.
|
||||
|
||||
This would block subsequent requests being made to the server, and more crucially responses being sent back from the server.
|
||||
|
||||
Server performance and optimisation only addressed the problem so far, but with larger payloads and pages being sent more frequently, something had to be done.
|
||||
|
||||
Frameworks, rose again to the challenge of delivering a better User Experience (UX) began to ship [Single Page Applications](https://en.wikipedia.org/wiki/Single-page_application) (**SPA**) to the client.
|
||||
|
||||
SPA's became a fast and effective ways to sending feature-rich applications to the client without the load being placed on the server.
|
||||
|
||||
Instead rendering the application would now be carried out wholly on the client device. Thus allowing the Server to send a single, simple, page to the client.
|
||||
|
||||
There are many benefits in providing a SPA to Clients. SPA's never needs a page refresh, since all the files (HTML/CSS/JS) had already been sent over the wire.
|
||||
|
||||
This only required the End-User's web browser to then read and render the application to the screen.
|
||||
|
||||
But SPA's came with their own hidden cost that comes with abstracting away the complexity. Recognising the many issues with SPA's from a holistic DX to a seamless UX/UI.
|
||||
|
||||
Frameworks began to appear in the ecosystem that allowed developers to build even more advanced Single-Page-Applications.
|
||||
|
||||
Some of these were developed by industry leaders, such as Google with their [Angular Project](https://angularjs.org/), [React](https://reactjs.org/) which was open sourced by Facebook. Or by the JS community themselves driving changes with [Preact](https://preactjs.com/), [Vue](https://vuejs.org/) and [Svelte](https://svelte.dev/), [Webpack](https://webpack.js.org/) & [Babel](https://babeljs.io/setup)
|
||||
|
||||
## The Status Quo
|
||||
|
||||
Its slightly hubris to suggest that the web development ecosystem had at all settled for any period of time, well at least long enough for a Status Quo to coalesce.
|
||||
|
||||
However, given the vibrancy and versatility of the ecosystem, a status quo had indeed began to take hold.
|
||||
|
||||
Rooted in the deepest annals of the developers psyche, was the slow conformity towards embracing UI frameworks to build the whole site as applications instead of the dynamic components that it was meant for.
|
||||
|
||||
Everything ended up being sent to the Client. From Rendering to Routing, bundled payload sizes drastically increased, and client devices were asked to do a lot more.
|
||||
|
||||
By placing the onus on the client, Server stress was indeed lessened. But there was a cost to this status quo.
|
||||
|
||||
The End-User experience was drastically suffering, for their devices now became the bottleneck, unable to execute the massive payloads that were being sent back from the server.
|
||||
|
||||
As demonstrated, JavaScript and its community are quick to change in certain places and slow in others. The gradual adoption of [EcmaScript Modules](https://tc39.es/ecma262/#sec-modules)(**ESM**) as a standard to the JavaScript spec was a complete sea-change to the ecosystem.
|
||||
|
||||
Prior to the formalisation of ESM, module usage in JS were often limited to libraries and were difficult to use outside the browser.
|
||||
|
||||
Using community developed conventions, helped push the goal of a modular ecosystem with [CommonJS](https://en.wikipedia.org/wiki/CommonJS)(**CJS**).
|
||||
|
||||
Node v12 shipped with ESM Modules as part of the standard in node. Signalling the start of something entirely new.
|
||||
|
||||
## The Great Migration
|
||||
|
||||
ESM adoption was indeed slow, the gradual migration from `require()` to `import()` took a while.
|
||||
|
||||
Now developing in an ESM world, allows for certain advantages to be exploited.
|
||||
|
||||
This wanting exploitation of new features have given way for another influx of new libraries, frameworks, tooling and a whole suite of new methods of writing JS.
|
||||
|
||||
We are now experiencing new tools in the ecosystem that feature ESM as defaults.
|
||||
|
||||
By doing so we can take full advantage of unbundled developer environments, allowing for projects to start-up in the tens of milliseconds, instead of whole seconds and full minutes.
|
||||
|
||||
Using ESM in the Browser, tools can build once and cache forever. Tree-shaking and code optimisations can occur, more frequently and with greater efficacy. Reducing massive bundle sizes down to a few hundred Kilobytes.
|
||||
|
||||
Tools like [Snowpack](https://www.snowpack.dev/) and [Vite](https://vitejs.dev/) introduce an whole new experience that developers were previously denied in their development process and that is speed.
|
||||
|
||||
With cut-edge DX features like [HMR](https://npm.io/package/esm-hmr) has quickly became the industry de facto, and build times reduced by a factor of 100x.
|
||||
|
||||
This new generation of ESM tools is extremely encouraging for web developers.
|
||||
|
||||
## A Brave New World
|
||||
|
||||
Into this new age ESM world, we have had a dearth of innovation from the established frameworks to address some of the root issues that plagued web development over its time.
|
||||
|
||||
Basic questions of : Websites or WebApp's were still unresolved. Where to render the site, on the server or on the client, perhaps a bit of both? What determines the need for dynamic content and what specifies content to be static?
|
||||
|
||||
Witnessing frameworks slowly go full circle and return to Server-Side-Rendering (_SSR_) their applications was in part only allowed to be considered in an ESM world, however it was bit of an admission of culpability of sorts.
|
||||
|
||||
By inadvertently admitting that the current model is flawed, opened up the space for a new form of discourse to enter, and help redefine the ecosystem moving forward.
|
||||
|
||||
SSR frameworks such as [Next.js](https://nextjs.org/), [Nuxt.js](https://nuxtjs.org/), [SvelteKit](https://kit.svelte.dev/), did help address some of the underling questions, within the current paradigm.
|
||||
|
||||
Developing methods and techniques to deliver production-stable SSR along with tooling and support for the developer.
|
||||
|
||||
But in a new age, retaining previously disputed tenants only aided the lack of innovation in this new dawn.
|
||||
|
||||
Jason Miller's formulations of an 'Island'-styled approach only augments the discussion with fresh new ideas about Website and Application development.
|
||||
|
||||
## The Golden Isles and its many Islands
|
||||
|
||||
In the introduction we placed a quote from Jason, describing the general concept of Island architecture. Let's revisit his words, since we have a better understanding of the context in which this is being proposed.
|
||||
|
||||
Jason asks us to think of a Island architecture as a static HTML document. One that is rendered entirely on the server.
|
||||
|
||||
The document contains multiple separate embedded applications, that are injected into placeholders or '_slots_', which form dynamic regions on the page.
|
||||
|
||||
The Server renders HTML outputs form each of these dynamic components, and places them onto the static document being sent back down to the End-User.
|
||||
|
||||
These slots, of dynamic regions, can then be '_hydrated_'. [Hydration](<https://en.wikipedia.org/wiki/Hydration_(web_development)>) is a process that allows for Client-Sided JS to convert and make static HTML, dynamic, reusing their initial server-rendered HTML.
|
||||
|
||||
This 'micro' architecture is similar to both 'micro-frontends' and 'micro-services'. Both share the concept of breaking applications into small indivisible units. But the problem is that a lot of the small modular units are rarely composed in HTML.
|
||||
|
||||
With Island-Architecture, he proposes a form of progressive enhancement for the dynamic components by using a technique known as _Partial Hydration_.
|
||||
|
||||
Lets look at this following analogy:
|
||||
|
||||
On our Static page, we have an image carousel. Such carousel needs to have some form of interactivity to load the next image after a certain amount of time has elapsed, along with navigation and pagination buttons on the carousel.
|
||||
|
||||
To do this we would need to implement some behaviour on our carousel.
|
||||
|
||||
In the traditional sense, we might be using a React Component to help create the aforementioned experience. In order to do this we would have too include the React-runtime plugin as a top-level `<script>` within our HTML document.
|
||||
|
||||
This means for our page, we need to wait for React to be fetched and downloaded, then parsed and executed, have it wait for the page to display the carousel before we receive the behaviour and functionality we expect from our small dynamic component.
|
||||
|
||||
Instead of this laborious process, one would simply render the carousel in HTML on the server and have a dedicated `<script>` that is emitted when the component for the carousel is displayed.
|
||||
|
||||
This would then load the functionality for the carousel in-place, transforming it instantly into a dynamic image slide show, with navigation.
|
||||
|
||||
## Island Hydration
|
||||
|
||||
By now the idea of Island-architecture must be settling in, and one must be thinking, this is just [Progressive Hydration](<https://en.wikipedia.org/wiki/Hydration_(web_development)#Progressive_rehydration>), and you wouldn't be overly off mark.
|
||||
|
||||
Progressive Hydration that is used in frameworks like: Angluar, React, Preact, Vue. Are individual components, which are loaded and then initialised over a period of time.
|
||||
|
||||
Using scheduling processes, and accounting for things like viewport visibility, content value, probability of interaction etc. They can abstract away the intricacies and delivery this form of hydration for developers.
|
||||
|
||||
By using Island styled components, this form of hydration essentially comes for **free**.
|
||||
|
||||
Since the larger dynamic components on a page are being initialised separately, not progressively. The difference lets individual regions on the page to become interactive without the page requiring to first load anything.
|
||||
|
||||
This expands further, as it doesn't need any form of ['Top-down Rendering'](https://developers.google.com/web/fundamentals/performance/rendering).
|
||||
|
||||
Since there is no outer `<div id='root'>` element that needs to be initialised before the inner contents can be exposed.
|
||||
|
||||
Every region of the page is an isolated unit, an island, on its own, connected to others by the HTML page. With such an approach the benefits do begin to stack up.
|
||||
|
||||
A key benefit is seen with the site performance. Since isolation is inherent, if a single issue affects a component, it wouldn't affect the other _islands_ on the page.
|
||||
|
||||
## Exploring the Island
|
||||
|
||||
As we explore further into the Island, we can see immediate trade differences between framework produced SSR solutions and those that could be provided by using Island Architecture.
|
||||
|
||||
Quickly wandering back to the Status Quo for a brief interlude. We use SSR with SPA's to help tackle the downside of SPA's and its SEO. Appealing to the search engines in this manner has another negative affect on the UX.
|
||||
|
||||
> "...visitors are left waiting for the actual functionality of a page to arrive while staring at a frustratingly fake version of that page." - Jason Miller
|
||||
|
||||
There are other issues that stem from traditional SSR, and being idly unawares of such performance pitfalls, gives rise to an orchestra of potential problems.
|
||||
|
||||
Further compounded with misconceptions on implementations and utilisations of solid SSR techniques, this practice is increasingly prominent amongst the Status Quoticians.
|
||||
|
||||
The one most obvious drawback with SSR is the amount of work JS has to do during the initial page load, is far excessive than is necessary, and is extremely inefficient use of resources.
|
||||
|
||||
We find with our "Islands" model, that with Server rendering is a fundamental part of how pages are delivered to the browser.
|
||||
|
||||
The responded HTML, would still contain all the rendered content that the user requested. With some islands yet to engage their client-sided interactivity. The document sent should contain all the content that the User would need.
|
||||
|
||||
An example of this would be a product page for a e-commerce business. A product page, using the Islands model would contain that products description, price etc, Having the dynamic components becoming interactive on demand.
|
||||
|
||||
We also discover that with the Islands model we have better accessibility and discoverability of our elements and the contents within.
|
||||
|
||||
Less code is eventually shipped from each island which is a massive cost-saving benefit.
|
||||
|
||||
However the conceptual idea of using Islands from a Web developers viewpoint is that, we get to come full circle and begin to deliver lightening fast user experiences without having the previous trade-offs and penalties that came from previous design models.
|
||||
|
||||
They're plenty of more important discoveries yet to be made when exploring the Island Architecture model in more detail.
|
||||
|
||||
Jason finished his post with the following:
|
||||
|
||||
> "It's possible...that adopting a model like this requires more up-front design thinking. There are far few batteries-included options available ...Who knows, maybe we can fix that." - August 2020
|
||||
|
||||
## Astrolands
|
||||
|
||||
<!-- Conclusion, final words. Here tie in Astro -->
|
||||
|
||||
Here at Astro, we fully embrace the principles ideas behind Jason's 'Island Architecture'. As a result, we have been hard at work trying to apply this new innovative concept into Web Development and the JS ecosystem.
|
||||
|
||||
We would like to take this time to encourage you to start exploring how Astro accomplishes this. And experience how easy it is to adopt as an architectural design philosophy.
|
|
@ -3,129 +3,185 @@ layout: ~/layouts/Main.astro
|
|||
title: Astro Components
|
||||
---
|
||||
|
||||
## ✨ `.astro` Syntax
|
||||
**Astro Components** (files ending with `.astro`) are the foundation of server-side templating in Astro. Think of the Astro component syntax as HTML enhanced with JavaScript.
|
||||
|
||||
Astro comes with its own server-side, component-based templating language. Think of it as HTML enhanced with the full power of JavaScript.
|
||||
Learning a new syntax can feel intimidating, so we carefully designed the Astro component syntax to feel as familiar to web developers as possible. It borrows heavily from patterns you likely already know: components, frontmatter, props, and JSX expressions. We're confident that this guide will have you writing Astro components in no time, especially if you are already familiar with HTML & JavaScript.
|
||||
|
||||
Learning a new syntax can be intimidating, but the `.astro` format has been carefully designed with familiarity in mind. It borrows heavily from patterns you likely already know—components, Frontmatter, and JSX-like expressions. We're confident that this guide will help you feel comfortable writing `.astro` files in no time.
|
||||
## Syntax Overview
|
||||
|
||||
---
|
||||
A single `.astro` file represents a single Astro component in your project. This pattern is known as a **Single-File Component (SFC)**. Both Svelte (`.svelte`) and Vue (`.vue`) also follow this pattern.
|
||||
|
||||
### The `.astro` format
|
||||
Below is a walk-through of the different pieces and features of the Astro component syntax. You can read it start-to-finish, or jump between sections.
|
||||
|
||||
If you're already familiar with **HTML or JavaScript**, you'll likely feel comfortable with `.astro` files right away.
|
||||
### HTML Template
|
||||
|
||||
Think of `.astro` as **component-oriented HTML**. Components are reusable, self-contained blocks of HTML and CSS that belong together.
|
||||
Astro component syntax is a superset of HTML. **If you know HTML, you already know enough to write your first Astro component.**
|
||||
|
||||
For example, this three-line file is a valid Astro component:
|
||||
|
||||
```html
|
||||
<!-- This is a valid Astro component -->
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Document</title>
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<h1>Hello world!</h1>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```html
|
||||
<!-- This is also a valid Astro component! -->
|
||||
<main>
|
||||
<!-- Example1.astro - Static HTML is a valid Astro component! -->
|
||||
<div class="example-1">
|
||||
<h1>Hello world!</h1>
|
||||
</main>
|
||||
</div>
|
||||
```
|
||||
|
||||
Developers have come up with a myriad of different techniques for composing blocks of HTML over the years, but far and away the most successful has been [JSX](https://reactjs.org/docs/introducing-jsx.html).
|
||||
An Astro component represents some snippet of HTML in your project. This can be a reusable component, or an entire page of HTML including `<html>`, `<head>` and `<body>` elements. See our guide on [Astro Pages](/guides/astro-pages) to learn how to build your first full HTML page with Astro.
|
||||
|
||||
We love JSX! In fact, `.astro` files borrow the highly-expressive expression syntax directly from JSX.
|
||||
**Every Astro component must include an HTML template.** While you can enhance your component in several ways (see below) at the end of the day its the HTML template that dictates what your rendered Astro component will look like.
|
||||
|
||||
```jsx
|
||||
<!-- This is an Astro component with expressions! -->
|
||||
<main>
|
||||
<h1>Hello {name}!</h1>
|
||||
<ul>
|
||||
{items.map((item) => (
|
||||
<li>{item}</li>
|
||||
))}
|
||||
</ul>
|
||||
<h2 data-hint={`Use JS template strings when you need to mix-in ${"variables"}.`}>So good!</h2>
|
||||
</main>
|
||||
### CSS Styles
|
||||
|
||||
CSS rules inside of a `<style>` tag are automatically scoped to that component. That means that you can reuse class names across multiple components, without worrying about conflicts. Styles are automatically extracted and optimized in the final build so that you don't need to worry about style loading.
|
||||
|
||||
For best results, you should only have one `<style>` tag per-Astro component. This isn’t necessarily a limitation, but it will often result in better-optimized CSS in your final build. When you're working with pages, the `<style>` tag can go nested inside of your page `<head>`. For standalone components, the `<style>` tag can go at the top-level of your template.
|
||||
|
||||
|
||||
```html
|
||||
<!-- Astro Component CSS example -->
|
||||
<style>
|
||||
.circle {
|
||||
background-color: red;
|
||||
border-radius: 999px;
|
||||
height: 50px;
|
||||
width: 50px;
|
||||
}
|
||||
<div class="circle"></div>
|
||||
```
|
||||
|
||||
`.astro` files also borrow the concept of [Frontmatter](https://jekyllrb.com/docs/front-matter/) from Markdown. Instead of introducing a new HTML-oriented `import` and `export` syntax, `.astro` just uses JavaScript.
|
||||
|
||||
```jsx
|
||||
---
|
||||
// This area is TypeScript (and therefore JavaScript)!
|
||||
import MyComponent from './MyComponent.astro'
|
||||
---
|
||||
|
||||
<html lang="en">
|
||||
```html
|
||||
<!-- Astro Page CSS example -->
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Document</title>
|
||||
<style>...</style>
|
||||
</head>
|
||||
<body>
|
||||
<MyComponent></MyComponent>
|
||||
</body>
|
||||
<body>...</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
### Data and Props
|
||||
Sass (an alternative to CSS) is also available via `<style lang="scss">`.
|
||||
|
||||
`.astro` components can define local variables inside of the Frontmatter script. These are automatically exposed to the content below.
|
||||
📚 Read our full guide on [Component Styling](/guides/styling) to learn more.
|
||||
|
||||
```jsx
|
||||
### Frontmatter Script
|
||||
|
||||
To build a dynamic components, we introduce the idea of a frontmatter component script. [Frontmatter](https://jekyllrb.com/docs/front-matter/) is a common pattern in Markdown, where some config/metadata is contained inside a code fence (`---`) at the top of the file. Astro does something similar, but with full support for JavaScript & TypeScript in your components.
|
||||
|
||||
Remember that Astro is a server-side templating language, so your component script will run during the build but only the HTML is rendered to the browser. To send JavaScript to the browser, you can use a `<script>` tag in your HTML template or [convert your component to use a frontend framework](/core-concepts/component-hydration) like React, Svelte, Vue, etc.
|
||||
|
||||
```astro
|
||||
---
|
||||
let name = 'world';
|
||||
// Anything inside the `---` code fence is your component script.
|
||||
// This JavaScript code runs at build-time.
|
||||
// See below to learn more about what you can do.
|
||||
console.log('This runs at build-time, is visible in the CLI output');
|
||||
// Tip: TypeScript is also supported out-of-the-box!
|
||||
const thisWorks: number = 42;
|
||||
---
|
||||
|
||||
<main>
|
||||
<h1>Hello {name}!</h1>
|
||||
</main>
|
||||
<div class="example-1">
|
||||
<h1>Hello world!</h1>
|
||||
</div>
|
||||
```
|
||||
|
||||
`.astro` components can also accept props when they are rendered. Public props are exposed on the `Astro.props` global.
|
||||
### Component Imports
|
||||
|
||||
```jsx
|
||||
An Astro component can reuse other Astro components inside of its HTML template. This becomes the foundation of our component system: build new components and then reuse them across your project.
|
||||
|
||||
To use an Astro component in your template, you first need to import it in the frontmatter component script. An Astro component is always the file's default import.
|
||||
|
||||
Once imported, you can use it like any other HTML element in your template. Note that an Astro component **MUST** begin with an uppercase letter. Astro will use this to distinguish between native HTML elements (`form`, `input`, etc.) and your custom Astro components.
|
||||
|
||||
```astro
|
||||
---
|
||||
// Import your components in your component script...
|
||||
import SomeComponent from './SomeComponent.astro';
|
||||
---
|
||||
<!-- ... then use them in your HTML! -->
|
||||
<div>
|
||||
<SomeComponent />
|
||||
</div>
|
||||
```
|
||||
|
||||
📚 You can also import and use components from other frontend frameworks like React, Svelte, and Vue. Read our guide on [Component Hydration](/core-concepts/component-hydration) to learn more.
|
||||
|
||||
### Dynamic JSX Expressions
|
||||
|
||||
Instead of inventing our own custom syntax for dynamic templating, we give you direct access to JavaScript values inside of your HTML, using something that feels just like [JSX](https://reactjs.org/docs/introducing-jsx.html).
|
||||
|
||||
Astro components can define local variables inside of the Frontmatter script. Any script variables are then automatically available in the HTML template below.
|
||||
|
||||
#### Dynamic Values
|
||||
|
||||
```astro
|
||||
---
|
||||
const name = "Your name here";
|
||||
---
|
||||
<div>
|
||||
<h1>Hello {name}!</h1>
|
||||
</div>
|
||||
```
|
||||
#### Dynamic Attributes
|
||||
|
||||
```astro
|
||||
---
|
||||
const name = "Your name here";
|
||||
---
|
||||
<div>
|
||||
<div data-name={name}>Attribute expressions supported</div>
|
||||
<div data-hint={`Use JS template strings to mix ${"variables"}.`}>So good!</div>
|
||||
</div>
|
||||
```
|
||||
|
||||
#### Dynamic HTML
|
||||
|
||||
```astro
|
||||
---
|
||||
const items = ["Dog", "Cat", "Platipus"];
|
||||
---
|
||||
<ul>
|
||||
{items.map((item) => (
|
||||
<li>{item}</li>
|
||||
))}
|
||||
</ul>
|
||||
```
|
||||
|
||||
|
||||
### Component Props
|
||||
|
||||
An Astro component can define and accept props. Props are available on the `Astro.props` global in your frontmatter script.
|
||||
|
||||
```astro
|
||||
---
|
||||
// Example: <SomeComponent greeting="(Optional) Hello" name="Required Name" />
|
||||
const { greeting = 'Hello', name } = Astro.props;
|
||||
---
|
||||
|
||||
<main>
|
||||
<h1>{greeting} {name}!</h1>
|
||||
</main>
|
||||
<div>
|
||||
<h1>{greeting}, {name}!</h1>
|
||||
</div>
|
||||
```
|
||||
|
||||
To define the props which your component accepts, you may export a TypeScript interface or type named `Props`.
|
||||
You can define your props with TypeScript by exporting a `Props` type interface. In the future, Astro will automatically pick up any exported `Props` interface and give type warnings/errors for your project.
|
||||
|
||||
```tsx
|
||||
```astro
|
||||
---
|
||||
// Example: <SomeComponent /> (WARNING: "name" prop is required)
|
||||
export interface Props {
|
||||
name: string;
|
||||
greeting?: string;
|
||||
}
|
||||
|
||||
const { greeting = 'Hello', name } = Astro.props;
|
||||
---
|
||||
|
||||
<main>
|
||||
<h1>{greeting} {name}!</h1>
|
||||
</main>
|
||||
<div>
|
||||
<h1>{greeting}, {name}!</h1>
|
||||
</div>
|
||||
```
|
||||
|
||||
### Slots
|
||||
|
||||
`.astro` files use the [`<slot>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/slot) element to enable component composition. Coming from React, this is the same concept as `children`. You can think of the `<slot>` element as a placeholder for markup which will be passed from outside of the component.
|
||||
`.astro` files use the [`<slot>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/slot) tag to enable component composition. Coming from React or Preact, this is the same concept as `children`. You can think of the `<slot>` element as a placeholder for markup which will be passed in from outside of the component.
|
||||
|
||||
```astro
|
||||
<!-- MyComponent.astro -->
|
||||
<!-- Example: MyComponent.astro -->
|
||||
<div id="my-component">
|
||||
<slot /> <!-- children will go here -->
|
||||
</div>
|
||||
|
@ -136,24 +192,24 @@ const { greeting = 'Hello', name } = Astro.props;
|
|||
</MyComponent>
|
||||
```
|
||||
|
||||
Slots are especially powerful when using **named slots**. Rather than a single `<slot>` element which renders _all_ children, named slots allow you to specify where certain children should be placed.
|
||||
Slots become even more powerful when using **named slots**. Rather than a single `<slot>` element which renders _all_ children, named slots allow you to specify multiple places where children should be placed.
|
||||
|
||||
> **Note** The `slot` attribute is not restricted to plain HTML, components can use `slot` as well!
|
||||
|
||||
```astro
|
||||
<!-- MyComponent.astro -->
|
||||
<!-- Example: MyComponent.astro -->
|
||||
<div id="my-component">
|
||||
<header>
|
||||
<slot name="header" /> <!-- children with the `slot="header"` attribute will go here -->
|
||||
<!-- children with the `slot="header"` attribute will go here -->
|
||||
<slot name="header" />
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<!-- children without a `slot` (or with the `slot="default"`) attribute will go here -->
|
||||
<slot />
|
||||
</main>
|
||||
|
||||
<footer>
|
||||
<slot name="footer"> <!-- children with the `slot="footer"` attribute will go here -->
|
||||
<!-- children with the `slot="footer"` attribute will go here -->
|
||||
<slot name="footer">
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
|
@ -165,7 +221,7 @@ Slots are especially powerful when using **named slots**. Rather than a single `
|
|||
</MyComponent>
|
||||
```
|
||||
|
||||
Slots also have the ability to render **fallback content**. When there are no matching children passed to a `<slot>`, a `<slot>` element will be replaced with its own children.
|
||||
Slots can also render **fallback content**. When there are no matching children passed to a `<slot>`, a `<slot>` element will render its own placeholder children.
|
||||
|
||||
```astro
|
||||
<!-- MyComponent.astro -->
|
||||
|
@ -174,34 +230,73 @@ Slots also have the ability to render **fallback content**. When there are no ma
|
|||
<h1>I will render when this slot does not have any children!</h1>
|
||||
</slot>
|
||||
</div>
|
||||
|
||||
<!-- Usage -->
|
||||
<MyComponent />
|
||||
```
|
||||
|
||||
### Fragments
|
||||
### Fragments & Multiple Elements
|
||||
|
||||
At the top-level of an `.astro` file, you may render any number of elements.
|
||||
An Astro component template can render as many top-level elements as you'd like. Unlike other UI component frameworks, you don't need to wrap everything in a single `<div>` if you'd prefer not to.
|
||||
|
||||
```html
|
||||
<!-- Look, no Fragment! -->
|
||||
<!-- An Astro component can multiple top-level HTML elements: -->
|
||||
<div id="a" />
|
||||
<div id="b" />
|
||||
<div id="c" />
|
||||
```
|
||||
|
||||
Inside of an expression, you must wrap multiple elements in a Fragment. Fragments must open with `<>` and close with `</>`.
|
||||
When working inside a JSX expression, however, you must wrap multiple elements inside of a **Fragment**. Fragments let you render a set of elements without adding extra nodes to the DOM. This is required in JSX expressions because of a limitation of JavaScript: You can never `return` more than one thing in a JavaScript function or expression. Using a Fragment solves this problem.
|
||||
|
||||
```jsx
|
||||
<div>
|
||||
{[0, 1, 2].map((id) => (
|
||||
A Fragment must open with `<>` and close with `</>`. Don't worry if you forget this, Astro's compiler will warn you that you need to add one.
|
||||
|
||||
```astro
|
||||
---
|
||||
const items = ["Dog", "Cat", "Platipus"];
|
||||
---
|
||||
<ul>
|
||||
{items.map((item) => (
|
||||
<>
|
||||
<div id={`a-${id}`} />
|
||||
<div id={`b-${id}`} />
|
||||
<div id={`c-${id}`} />
|
||||
<li>Red {item}</li>
|
||||
<li>Blue {item}</li>
|
||||
<li>Green {item}</li>
|
||||
</>
|
||||
))}
|
||||
</div>
|
||||
</ul>
|
||||
```
|
||||
|
||||
### `.astro` versus `.jsx`
|
||||
### Slots
|
||||
|
||||
Sometimes, an Astro component will be passed children. This is especially common for components like sidebars or dialog boxes that represent generic "wrappers” around content.
|
||||
|
||||
```astro
|
||||
<WrapChildrenWithText>
|
||||
<img src="https://placehold.co/400" />
|
||||
<WrapChildrenWithText>
|
||||
```
|
||||
|
||||
Astro provides a `<slot />` component so that you can control where any children are rendered within the component. This is heavily inspired by the [`<slot>` HTML element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/slot).
|
||||
|
||||
```astro
|
||||
---
|
||||
// Example: components/WrapChildrenWithText.astro
|
||||
// Usage: <WrapChildrenWithText><img src="https://placehold.co/400" /><WrapChildrenWithText>
|
||||
// Renders: <h1>Begin</h1><img src="https://placehold.co/400" /><h1>End</h1>
|
||||
---
|
||||
<h1>Begin</h1>
|
||||
<!-- slot: any given children are injected here -->
|
||||
<slot />
|
||||
<h1>End</h1>
|
||||
```
|
||||
|
||||
<!-- TODO: https://github.com/snowpackjs/astro/issues/600
|
||||
If you don't provide a `<slot />` component in your HTML template, any children passed to your component will not be rendered. -->
|
||||
|
||||
<!-- TODO: https://github.com/snowpackjs/astro/issues/360
|
||||
Document Named Slots -->
|
||||
|
||||
|
||||
## Comparing `.astro` versus `.jsx`
|
||||
|
||||
`.astro` files can end up looking very similar to `.jsx` files, but there are a few key differences. Here's a comparison between the two formats.
|
||||
|
||||
|
@ -223,7 +318,7 @@ Inside of an expression, you must wrap multiple elements in a Fragment. Fragment
|
|||
| Special Characters | ` ` | `{'\xa0'}` or `{String.fromCharCode(160)}` |
|
||||
| Attributes | `dash-case` | `camelCase` |
|
||||
|
||||
### URL resolution
|
||||
## URL resolution
|
||||
|
||||
It’s important to note that Astro **won’t** transform HTML references for you. For example, consider an `<img>` tag with a relative `src` attribute inside `src/pages/about.astro`:
|
||||
|
||||
|
@ -234,7 +329,7 @@ It’s important to note that Astro **won’t** transform HTML references for yo
|
|||
|
||||
Since `src/pages/about.astro` will build to `/about/index.html`, you may not have expected that image to live at `/about/thumbnail.png`. So to fix this, choose either of two options:
|
||||
|
||||
#### Option 1: Absolute URLs
|
||||
### Option 1: Absolute URLs
|
||||
|
||||
```html
|
||||
<!-- ✅ Correct: references public/thumbnail.png -->
|
||||
|
@ -243,9 +338,9 @@ Since `src/pages/about.astro` will build to `/about/index.html`, you may not hav
|
|||
|
||||
The recommended approach is to place files within `public/*`. This references a file it `public/thumbnail.png`, which will resolve to `/thumbnail.png` at the final build (since `public/` ends up at `/`).
|
||||
|
||||
#### Option 2: Asset import references
|
||||
### Option 2: Asset import references
|
||||
|
||||
```jsx
|
||||
```astro
|
||||
---
|
||||
// ✅ Correct: references src/thumbnail.png
|
||||
import thumbnailSrc from './thumbnail.png';
|
||||
|
@ -256,4 +351,7 @@ import thumbnailSrc from './thumbnail.png';
|
|||
|
||||
If you’d prefer to organize assets alongside Astro components, you may import the file in JavaScript inside the component script. This works as intended but this makes `thumbnail.png` harder to reference in other parts of your app, as its final URL isn’t easily-predictable (unlike assets in `public/*`, where the final URL is guaranteed to never change).
|
||||
|
||||
|
||||
[code-ext]: https://marketplace.visualstudio.com/items?itemName=astro-build.astro-vscode
|
||||
|
||||
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
---
|
||||
layout: ~/layouts/Main.astro
|
||||
title: Astro Pages
|
||||
title: Pages
|
||||
---
|
||||
|
||||
**Pages** are a special type of [Astro Component](./astro-components) that handle routing, data loading, and templating for each page of your website. You can think of them like any other Astro component, just with extra responsibilities.
|
||||
**Pages** are a special type of [Astro Component](/core-concepts/astro-components) that handle routing, data loading, and templating for each page of your website. You can think of them like any other Astro component, just with extra responsibilities.
|
||||
|
||||
Astro also supports Markdown for content-heavy pages, like blog posts and documentation. See [Markdown Content](./markdown-content.md) for more information on writing pages with Markdown.
|
||||
Astro also supports Markdown for content-heavy pages, like blog posts and documentation. See [Markdown Content](/guides/markdown-content) for more information on writing pages with Markdown.
|
||||
|
||||
## File-based Routing
|
||||
|
||||
|
@ -13,8 +13,6 @@ Astro uses Pages to do something called **file-based routing.** Every file in yo
|
|||
|
||||
Astro Components (`.astro`) and Markdown Files (`.md`) are the only supported formats for pages. Other page types (like a `.jsx` React component) are not supported, but you can use anything as a UI component inside of an `.astro` page to achieve a similar result.
|
||||
|
||||
### Examples
|
||||
|
||||
```
|
||||
src/pages/index.astro -> mysite.com/
|
||||
src/pages/about.astro -> mysite.com/about
|
||||
|
@ -23,34 +21,9 @@ src/pages/about/me.astro -> mysite.com/about/me
|
|||
src/pages/posts/1.md -> mysite.com/posts/1
|
||||
```
|
||||
|
||||
## Data Loading
|
||||
|
||||
Astro pages can fetch data to help generate your pages. Astro provides two different tools to pages to help you do this: **fetch()** and **top-level await.**
|
||||
|
||||
```astro
|
||||
---
|
||||
// Example: Astro component scripts run at build time
|
||||
const response = await fetch('http://example.com/movies.json');
|
||||
const data = await response.json();
|
||||
console.log(data);
|
||||
---
|
||||
<!-- Output the result to the page -->
|
||||
<div>{JSON.stringify(data)}</div>
|
||||
```
|
||||
|
||||
### `fetch()`
|
||||
|
||||
Astro pages have access to the global `fetch()` function in their setup script. `fetch()` is a native JavaScript API ([MDN](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch)) that lets you make HTTP requests for things like APIs and resources.
|
||||
|
||||
Even though Astro component scripts run inside of Node.js (and not in the browser) Astro provides this native API so that you can fetch data at page build time.
|
||||
|
||||
### Top-level await
|
||||
|
||||
`await` is another native JavaScript feature that lets you await the response of some asynchronous promise ([MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await)). Astro supports `await` in the top-level of your component script.
|
||||
|
||||
## Page Templating
|
||||
|
||||
All Astro components are responsible for returning HTML. Astro Pages return HTML as well, but have the unique responsibility of returning a full `<html>...</html>` page response, including `<head>` ([MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/head)) and `<body>` ([MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/body)).
|
||||
All Astro components are responsible for returning HTML. Astro Pages return HTML as well, but have the unique responsibility of returning a full `<html>...</html>` page response, including `<head>` ([MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/head)) and `<body>` ([MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/body)).
|
||||
|
||||
`<!doctype html>` is optional, and will be added automatically.
|
||||
|
||||
|
@ -68,3 +41,20 @@ All Astro components are responsible for returning HTML. Astro Pages return HTML
|
|||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
## Data Loading
|
||||
|
||||
Astro pages can fetch data to help generate your pages. Astro provides two different tools to pages to help you do this: **fetch()** and **top-level await.**
|
||||
|
||||
📚 Read our [full guide](/guides/data-fetching) on data-fetching to learn more.
|
||||
|
||||
```astro
|
||||
---
|
||||
// Example: Astro component scripts run at build time
|
||||
const response = await fetch('http://example.com/movies.json');
|
||||
const data = await response.json();
|
||||
console.log(data);
|
||||
---
|
||||
<!-- Output the result to the page -->
|
||||
<div>{JSON.stringify(data)}</div>
|
||||
```
|
|
@ -3,7 +3,7 @@ layout: ~/layouts/Main.astro
|
|||
title: Collections
|
||||
---
|
||||
|
||||
**Collections** are a special type of [Page](./astro-pages) that help you generate multiple pages from a larger set of data. Example use-cases include:
|
||||
**Collections** are a special type of [Page](/core-concepts/astro-pages) that help you generate multiple pages from a larger set of data. Example use-cases include:
|
||||
|
||||
- Pagination: `/posts/1`, `/posts/2`, etc.
|
||||
- Grouping content by author: `/author/fred`, `/author/matthew`, etc.
|
||||
|
@ -29,7 +29,7 @@ To create a new Astro Collection, you must do three things:
|
|||
3. Define and export `createCollection` function: this tells Astro how to load and structure your collection data. Check out the examples below for documentation on how it should be implemented. It MUST be named `createCollection` and it must be exported.
|
||||
|
||||
- Example: `export async function createCollection() { /* ... */ }`
|
||||
- API Reference: [createCollection][collection-api]
|
||||
- API Reference: [createCollection](/reference/api-reference#collections-api)
|
||||
|
||||
## Example: Simple Pagination
|
||||
|
||||
|
@ -153,6 +153,8 @@ export async function createCollection() {
|
|||
|
||||
## Example: Individual Pages from a Collection
|
||||
|
||||
**Note**: collection.data and .params are being fetched async, use optional chaining or some other way of handling this in template. Otherwise you will get build errors.
|
||||
|
||||
```jsx
|
||||
---
|
||||
// Define the `collection` prop.
|
||||
|
@ -188,9 +190,10 @@ export async function createCollection() {
|
|||
---
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Pokemon: {collection.params.name}</head>
|
||||
<title>Pokemon: {collection.params?.name}</title>
|
||||
</head>
|
||||
<body>
|
||||
Who's that pokemon? It's {collection.data[0].name}!
|
||||
Who's that pokemon? It's {collection.data[0]?.name}!
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
@ -201,13 +204,8 @@ export async function createCollection() {
|
|||
|
||||
### 📚 Further Reading
|
||||
|
||||
- [Fetching data in Astro][docs-data]
|
||||
- API Reference: [collection][collection-api]
|
||||
- API Reference: [createCollection()][create-collection-api]
|
||||
- API Reference: [Creating an RSS feed][create-collection-api]
|
||||
- [Fetching data in Astro](/guides/data-fetching)
|
||||
- API Reference: [collection](/reference/api-reference#collections-api)
|
||||
- API Reference: [createCollection()](/reference/api-reference#createcollection)
|
||||
- API Reference: [Creating an RSS feed](/reference/api-reference#rss-feed)
|
||||
|
||||
[docs-data]: ../README.md#-fetching-data
|
||||
[collection-api]: ./api.md#collection
|
||||
[create-collection-api]: ./api.md#createcollection
|
||||
[example-blog]: ../examples/blog
|
||||
[fetch-content]: ./api.md#fetchcontent
|
||||
|
|
|
@ -1,39 +1,91 @@
|
|||
---
|
||||
layout: ~/layouts/Main.astro
|
||||
title: React, Svelte, Vue, etc.
|
||||
title: Partial Hydration in Astro
|
||||
---
|
||||
|
||||
By default, Astro generates your site with zero client-side JavaScript. If you use any frontend UI components (React, Svelte, Vue, etc.) Astro will automatically render them **on the server**, generating only HTML and CSS without any client-side JavaScript. This makes your site as fast as possible by default.
|
||||
**Astro generates every website with zero client-side JavaScript, by default.** Use any frontend UI component that you'd like (React, Svelte, Vue, etc.) and Astro will automatically render it to HTML at build-time and strip away all JavaScript. This keeps every site fast by default.
|
||||
|
||||
```
|
||||
But sometimes, client-side JavaScript is required. This guide shows how interactive components work in Astro using a technique called partial hydration.
|
||||
|
||||
```astro
|
||||
---
|
||||
// Example: Importing and then using a React component.
|
||||
// By default, Astro renders this to HTML and CSS during
|
||||
// your build, with no client-side JavaScript.
|
||||
// (Need client-side JavaScript? Read on...)
|
||||
import MyReactComponent from '../components/MyReactComponent.jsx';
|
||||
---
|
||||
<!-- By default: Astro renders this on the server,
|
||||
generating HTML and CSS, but no client-side JavaScript. -->
|
||||
<!-- 100% HTML, Zero JavaScript! -->
|
||||
<MyReactComponent />
|
||||
```
|
||||
|
||||
However, there are plenty of cases where you might like to include an interactive component on your page:
|
||||
## Concept: Partial Hydration
|
||||
|
||||
There are plenty of cases where you need an interactive UI component to run in the browser:
|
||||
|
||||
- An image carousel
|
||||
- An auto-complete search bar
|
||||
- A mobile sidebar open/close button
|
||||
- A "Buy Now" button
|
||||
|
||||
With Astro, you can hydrate these components individually, without forcing the rest of the page to ship any other unnecesary JavaScript. This technique is called **partial hydration.**
|
||||
In Astro, it's up to you as the developer to explicitly "opt-in" any components on the page that need to run in the browser. Astro can then use this info to know exactly what JavaScript is needed, and only hydrate exactly what's needed on the page. This technique is is known as partial hydration.
|
||||
|
||||
## Hydrate Frontend Components
|
||||
**Partial hydration** -- the act of only hydrating the individual components that require JavaScript and leaving the rest of your site as static HTML -- may sound relatively straightforward. It should! Websites have been built this way for decades. It was only recently that Single-Page Applications (SPAs) introduced the idea that your entire website is written in JavaScript and compiled/rendered by every user in the browser.
|
||||
|
||||
Astro renders every component on the server **at build time**. To hydrate any server-rendered component on the client **at runtime**, you may use any of the following techniques:
|
||||
_Note: Partial hydration is sometimes called "progressive enhancement" or "progressive hydration." While there are slight nuances between the terms, for our purposes you can think of these all as synonyms of the same concept._
|
||||
|
||||
- `<MyComponent client:load />` will hydrate the component on page load.
|
||||
- `<MyComponent client:idle />` will use [requestIdleCallback()][mdn-ric] to hydrate the component as soon as main thread is free.
|
||||
- `<MyComponent client:visible />` will use an [IntersectionObserver][mdn-io] to hydrate the component when the element enters the viewport.
|
||||
- `<MyComponent client:media={QUERY} />` will use [matchMedia][mdn-mm] to hydrate the component when a media query is matched.
|
||||
**Partial hydration is the secret to Astro's fast-by-default performance story.** Next.js, Gatsby, and other JavaScript frameworks cannot support partial hydration because they imagine your entire website/page as a single JavaScript application.
|
||||
|
||||
## Hydrate Astro Components
|
||||
## Concept: Island Architecture
|
||||
|
||||
Astro components (`.astro`) are HTML-only templating languages with no client-side runtime. You cannot hydrate an Astro component to run on the client (because the JavaScript front-matter only ever runs at build time).
|
||||
**Island architecture** is the idea of using partial hydration to build entire websites. Island architecture is an alternative to the popular idea of building your website into a client-side JavaScript bundle that must be shipped to the user.
|
||||
|
||||
If you want to make your Astro component interactive on the client, you should convert it to React, Svelte, or Vue. Otherwise, you can consider adding a `<script>` tag to your Astro component that will run JavaScript on the page.
|
||||
To quote Jason Miller, who [coined the phrase](https://jasonformat.com/islands-architecture/):
|
||||
|
||||
> In an "islands" model, server rendering is not a bolt-on optimization aimed at improving SEO or UX. Instead, it is a fundamental part of how pages are delivered to the browser. The HTML returned in response to navigation contains a meaningful and immediately renderable representation of the content the user requested.
|
||||
|
||||
Besides the obvious performance benefits of sending less JavaScript down to the browser, there are two key benefits to island architecture:
|
||||
|
||||
- **Components load individually.** A lightweight component (like a sidebar toggle) will load and render quickly without being blocked by the heavier components on the page.
|
||||
- **Components render in isolation.** Each part of the page is an isolated unit, and a performance issue in one unit won't directly affect the others.
|
||||
|
||||
![diagram](https://res.cloudinary.com/wedding-website/image/upload/v1596766231/islands-architecture-1.png)
|
||||
|
||||
|
||||
|
||||
## Hydrate Interactive Components
|
||||
|
||||
Astro renders every component on the server **at build time**. To hydrate components on the client **at runtime**, you may use any of the following `client:*` directives. A directive is a component attribute (always with a `:`) which tells Astro how your component should be rendered.
|
||||
|
||||
```astro
|
||||
---
|
||||
// Example: hydrating a React component in the browser.
|
||||
import MyReactComponent from '../components/MyReactComponent.jsx';
|
||||
---
|
||||
<!-- "client:visible" means the component won't load any client-side
|
||||
JavaScript until it becomes visible in the user's browser. -->
|
||||
<MyReactComponent client:visible />
|
||||
```
|
||||
|
||||
### `<MyComponent client:load />`
|
||||
Hydrate the component on page load.
|
||||
|
||||
### `<MyComponent client:idle />`
|
||||
Hydrate the component as soon as main thread is free (uses [requestIdleCallback()][mdn-ric]).
|
||||
|
||||
### `<MyComponent client:visible />`
|
||||
Hydrate the component as soon as the element enters the viewport (uses [IntersectionObserver][mdn-io]). Useful for content lower down on the page.
|
||||
|
||||
### `<MyComponent client:media={QUERY} />`
|
||||
Hydrate the component as soon as the browser matches the given media query (uses [matchMedia][mdn-mm]). Useful for sidebar toggles, or other elements that should only display on mobile or desktop devices.
|
||||
|
||||
## Can I Hydrate Astro Components?
|
||||
|
||||
[Astro components](./astro-components) (`.astro` files) are HTML-only templating components with no client-side runtime. If you try to hydrate an Astro component with a `client:` modifier, you will get an error.
|
||||
|
||||
To make your Astro component interactive, you will need to convert it to the frontend framework of your choice: React, Svelte, Vue, etc. If you have no preference, we reccomend React or Preact as most similar to Astro's syntax.
|
||||
|
||||
Alternatively, you could add a `<script>` tag to your Astro component HTML template and send JavaScript to the browser that way. While this is fine for the simple stuff, we recommend a frontend framework for more complex interactive components.
|
||||
|
||||
[mdn-io]: https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API
|
||||
[mdn-ric]: https://developer.mozilla.org/en-US/docs/Web/API/Window/requestIdleCallback
|
||||
|
|
|
@ -3,17 +3,17 @@ layout: ~/layouts/Main.astro
|
|||
title: Layouts
|
||||
---
|
||||
|
||||
**Layouts** are a special type of [Component](./astro-components) that help you share and reuse common page layouts within your project.
|
||||
**Layouts** are a special type of [Component](/core-concepts/astro-components) that help you share and reuse common page layouts within your project.
|
||||
|
||||
Layouts are just like any other reusable Astro component. There's no new syntax or APIs to learn. However, reusable page layouts are such a common pattern in web development that we created this guide to help you use them.
|
||||
|
||||
## Usage
|
||||
|
||||
Astro layouts support props, slots, and all of the other features of Astro components. Layouts are just normal components, after all!
|
||||
Astro layouts support props, slots, and all of the other features of Astro components. Layouts are just normal components, after all!
|
||||
|
||||
Unlike other components, layouts will often contain the full page `<html>`, `<head>` and `<body>` (often referred to as the **page shell**).
|
||||
|
||||
It's a common pattern to put all of your layout components in a single `src/layouts` directory.
|
||||
It's a common pattern to put all of your layout components in a single `src/layouts` directory.
|
||||
|
||||
## Example
|
||||
|
||||
|
@ -39,7 +39,7 @@ const {title} = Astro.props;
|
|||
</html>
|
||||
```
|
||||
|
||||
📚 The `<slot />` element lets Astro components define where any children elements (passed to the layout) should go. Learn more about how `<slot/>` works in our [Astro Component guide.](/docs/core-concepts/astro-components.md)
|
||||
📚 The `<slot />` element lets Astro components define where any children elements (passed to the layout) should go. Learn more about how `<slot/>` works in our [Astro Component guide.](/core-concepts/astro-components)
|
||||
|
||||
Once you have your first layout, You can use it like you would any other component on your page. Remember that your layout contains your page `<html>`, `<head>`, and `<body>`. You only need to provide the custom page content.
|
||||
|
||||
|
@ -54,10 +54,12 @@ import BaseLayout from '../layouts/BaseLayout.astro'
|
|||
</BaseLayout>
|
||||
```
|
||||
|
||||
|
||||
## Nesting Layouts
|
||||
|
||||
You can nest layouts when you want to create more specific page types without copy-pasting. It is common in Astro to have one generic `BaseLayout` and then many more specific layouts (`PostLayout`, `ProductLayout`, etc.) that reuse and build on top of it.
|
||||
|
||||
|
||||
```astro
|
||||
---
|
||||
// src/layouts/PostLayout.astro
|
||||
|
@ -91,7 +93,7 @@ const {title, description} = Astro.props;
|
|||
<link href="https://fonts.googleapis.com/css2?family=Spectral:ital,wght@0,400;0,700;1,400;1,700&display=swap" rel="stylesheet">
|
||||
```
|
||||
|
||||
Notice how this layout doesn't include your page shell, and only includes some generic elements that should go in your `<head>`. This lets you combine multiple layout components together, to include things
|
||||
Notice how this layout doesn't include your page shell, and only includes some generic elements that should go in your `<head>`. This lets you combine multiple layout components together with more control over the overall page structure.
|
||||
|
||||
```astro
|
||||
---
|
||||
|
@ -117,14 +119,13 @@ The one downside to this approach is that you'll need to define the `<html>`, `<
|
|||
|
||||
## Markdown Layouts
|
||||
|
||||
Layouts are essential for Markdown files. Markdown files can declare a layout in the file frontmatter. Each Markdown file will be rendered to HTML and then injected into the layout's `<slot />` location.
|
||||
Layouts are essential for Markdown files. Markdown files can declare a layout in the file frontmatter. Each Markdown file will be rendered to HTML and then injected into the layout's `<slot />` location.
|
||||
|
||||
```markdown
|
||||
---
|
||||
title: Blog Post
|
||||
layout: ../layouts/PostLayout.astro
|
||||
---
|
||||
|
||||
This blog post will be **rendered** inside of the `<PostLayout />` layout.
|
||||
```
|
||||
|
||||
|
@ -151,4 +152,4 @@ const { content } = Astro.props;
|
|||
</html>
|
||||
```
|
||||
|
||||
📚 Learn more about Astro's markdown support in our [Markdown guide](/docs/guides/markdown-content.md).
|
||||
📚 Learn more about Astro's markdown support in our [Markdown guide](/guides/markdown-content).
|
||||
|
|
|
@ -9,8 +9,7 @@ Astro includes an opinionated folder layout for your project. Every Astro projec
|
|||
- `public/*` - Your non-code assets (fonts, icons, etc.)
|
||||
- `package.json` - A project manifest.
|
||||
|
||||
The easiest way to set up your new project is with `npm init astro`. Check out our [Installation Guide](/docs/quick-start.md) for a walkthrough of how to set up your project automatically (with `npm init astro`) or manually.
|
||||
|
||||
The easiest way to set up your new project is with `npm init astro`. Check out our [Installation Guide](/quick-start) for a walkthrough of how to set up your project automatically (with `npm init astro`) or manually.
|
||||
## Project Structure
|
||||
|
||||
```
|
||||
|
@ -27,31 +26,31 @@ The easiest way to set up your new project is with `npm init astro`. Check out o
|
|||
|
||||
The src folder is where most of your project source code lives. This includes:
|
||||
|
||||
- [Astro Components](/docs/core-concepts/astro-components.md)
|
||||
- [Pages](/docs/core-concepts/astro-pages.md)
|
||||
- [Markdown](/docs/core-concepts/astro-pages.md)
|
||||
- [Layouts](/docs/core-concepts/astro-pages.md)
|
||||
- [Frontend JS Components](/docs/core-concepts/component-hydration.md)
|
||||
- [Styling (CSS, Sass)](/docs/guides/styling.md)
|
||||
- [Astro Components](/core-concepts/astro-components)
|
||||
- [Pages](/core-concepts/astro-pages)
|
||||
- [Markdown](/core-concepts/astro-pages)
|
||||
- [Layouts](/core-concepts/astro-pages)
|
||||
- [Frontend JS Components](/core-concepts/component-hydration)
|
||||
- [Styling (CSS, Sass)](/guides/styling)
|
||||
|
||||
Astro has complete control over how these files get processed, optimized, and bundled in your final site build. Some files (like Astro components) never make it to the browser directly and are instead rendered to HTML. Other files (like CSS) are sent to the browser but may be bundled with other CSS files depending on how your site uses.
|
||||
|
||||
### `src/components`
|
||||
|
||||
[Components](/docs/core-concepts/astro-components.md) are reusable units of UI for your HTML pages. It is recommended (but not required) that you put your components in this directory. How you organize them within this directory is up to you.
|
||||
[Components](/core-concepts/astro-components) are reusable units of UI for your HTML pages. It is recommended (but not required) that you put your components in this directory. How you organize them within this directory is up to you.
|
||||
|
||||
Your non-Astro UI components (React, Preact, Svelte, Vue, etc.) can also live in the `src/components` directory. Astro will automatically render all components to HTML unless you've enabled a frontend component via partial hydration.
|
||||
|
||||
### `src/layouts`
|
||||
|
||||
[Layouts](/docs/core-concepts/layouts.md) are reusable components for HTML page layouts. It is recommended (but not required) that you put your layout components in this directory. How you organize them within this directory is up to you.
|
||||
[Layouts](/core-concepts/layouts) are reusable components for HTML page layouts. It is recommended (but not required) that you put your layout components in this directory. How you organize them within this directory is up to you.
|
||||
|
||||
### `src/pages`
|
||||
|
||||
[Pages](/docs/core-concepts/astro-pages.md) contain all pages (`.astro` and `.md` supported) for your website. It is **required** that you put your pages in this directory.
|
||||
|
||||
[Pages](/core-concepts/astro-pages) contain all pages (`.astro` and `.md` supported) for your website. It is **required** that you put your pages in this directory.
|
||||
|
||||
### `public/`
|
||||
|
||||
For most users, the majority of your files will live inside of the `src/` directory so that Astro can properly handle and optimize them in your final build. By contrast, the `public/` directory is the place for any files to live outside of the Astro build process.
|
||||
|
||||
If you put a file into the public folder, it will not be processed by Astro. Instead it will be copied into the build folder untouched. This can be useful for assets like images and fonts, or when you need to include a specific file like `robots.txt` or `manifest.webmanifest`.
|
||||
If you put a file into the public folder, it will not be processed by Astro. Instead it will be copied into the build folder untouched. This can be useful for assets like images and fonts, or when you need to include a specific file like `robots.txt` or `manifest.webmanifest`.
|
|
@ -1,205 +0,0 @@
|
|||
---
|
||||
layout: ~/layouts/Main.astro
|
||||
title: UI Renderers
|
||||
---
|
||||
|
||||
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.
|
||||
|
||||
## Add a renderer to Astro
|
||||
|
||||
Astro enables a few popular framework renderers by default. If you want to add a new renderer to your project, you first need to set the built-in renderers that you care about.
|
||||
|
||||
```js
|
||||
// astro.config.js
|
||||
export default {
|
||||
renderers: [
|
||||
// Add the framework renderers that you want to enable for your project.
|
||||
// If you set an empty array here, no UI frameworks will work.
|
||||
// '@astrojs/renderer-svelte',
|
||||
// '@astrojs/renderer-vue',
|
||||
// '@astrojs/renderer-react',
|
||||
// '@astrojs/renderer-preact',
|
||||
],
|
||||
};
|
||||
```
|
||||
|
||||
To add a new custom renderer, install the npm package dependency in your project and then update the `renderers` array to include it:
|
||||
|
||||
```js
|
||||
// astro.config.js
|
||||
export default {
|
||||
renderers: ['my-custom-renderer', '@astrojs/renderer-svelte', '@astrojs/renderer-vue', '@astrojs/renderer-react', '@astrojs/renderer-preact'],
|
||||
};
|
||||
```
|
||||
|
||||
#### Managing Framework Versions
|
||||
|
||||
In Astro, the renderer plugin defines which version of your framework to use with Astro. This should be set to as wide of a range as possible, but often will be pinned to a specific major version:
|
||||
|
||||
- `@astrojs/renderer-vue`: `"vue": "^3.0.0"`
|
||||
- `@astrojs/renderer-react`: `"react": "^17.0.0"`
|
||||
- See all: https://github.com/snowpackjs/astro/tree/main/packages/renderers
|
||||
|
||||
This is required because the renderer itself also uses these packages and requires a specific API to work. For example, If the user updated from Vue 2 to Vue 3 (or vice versa) then the renderer itself would break since the `vue` package would have changed.
|
||||
|
||||
**What if I want to use a beta framework (ex: react@next)?** Check to see if the renderer has a `@next` version that you could manually install and use. If one doesn't exist, feel free to request it: https://github.com/snowpackjs/astro/issues/new/choose
|
||||
|
||||
**What if I need to override the framework version in my project?** You can use the "resolutions" feature of many npm package managers to override or pin the framework version for your entire project. Just be sure to select a version that is compatible with your renderer:
|
||||
|
||||
- **yarn:** https://classic.yarnpkg.com/en/docs/selective-version-resolutions/
|
||||
- **pnpm:** https://pnpm.io/package_json#pnpmoverrides
|
||||
- **npm:** see https://stackoverflow.com/questions/15806152/how-do-i-override-nested-npm-dependency-versions
|
||||
|
||||
## 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);
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
[astro-config]: ./config.md
|
|
@ -5,4 +5,4 @@ title: Examples
|
|||
|
||||
If you prefer to learn by example, check out our [Examples Library](https://github.com/snowpackjs/astro/tree/main/examples) on GitHub.
|
||||
|
||||
<!-- Once we merge astro-docs back into the main repo, we can actually fetch the list of examples at build-time by scanning the examples/ directory! -->
|
||||
<!-- Once we merge astro-docs back into the main repo, we can actually fetch the list of examples at build-time by scanning the examples/ directory! -->
|
|
@ -3,24 +3,27 @@ layout: ~/layouts/Main.astro
|
|||
title: Data Fetching
|
||||
---
|
||||
|
||||
Astro support `fetch()` and "top-level await" to help you do remote data fetching inside of your page. See the ["Data Loading" Pages section](/docs/core-concepts/astro-pages.md#data-loading) for more info.
|
||||
Astro components and pages can fetch remote data to help generate your pages. Astro provides two different tools to pages to help you do this: **fetch()** and **top-level await.**
|
||||
|
||||
**Important:** These are not yet available inside of non-page Astro components. Instead, do all of your data loading inside of your pages, and then pass them to your components as props.
|
||||
### `fetch()`
|
||||
|
||||
Astro pages have access to the global `fetch()` function in their setup script. `fetch()` is a native JavaScript API ([MDN](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch)) that lets you make HTTP requests for things like APIs and resources.
|
||||
|
||||
Even though Astro component scripts run inside of Node.js (and not in the browser) Astro provides this native API so that you can fetch data at page build time.
|
||||
|
||||
## Example
|
||||
|
||||
```astro
|
||||
// Example: src/pages/foo.astro
|
||||
// top-level `fetch()` and `await` are both supported natively in Astro (pages only).
|
||||
const allPokemonResponse = await fetch(`https://pokeapi.co/api/v2/pokemon?limit=150`);
|
||||
const allPokemonResult = await allPokemonResponse.json();
|
||||
const allPokemon = allPokemonResult.results;
|
||||
---
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Original 150 Pokemon</head>
|
||||
<body>
|
||||
{allPokemon.map((pokemon) => (<h1>{pokemon.name}</h1>))}
|
||||
</body>
|
||||
</html>
|
||||
const response = await fetch('http://example.com/movies.json');
|
||||
const data = await response.json();
|
||||
// Remember: Astro component scripts log to the CLI
|
||||
console.log(data);
|
||||
---
|
||||
<!-- Output the result to the page -->
|
||||
<div>{JSON.stringify(data)}</div>
|
||||
```
|
||||
### Top-level await
|
||||
|
||||
`await` is another native JavaScript feature that lets you await the response of some asynchronous promise ([MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await)). Astro supports `await` in the top-level of your component script.
|
||||
|
||||
**Important:** These are not yet available inside of non-page Astro components. Instead, do all of your data loading inside of your pages, and then pass them to your components as props.
|
||||
|
|
|
@ -1,25 +1,27 @@
|
|||
---
|
||||
layout: ~/layouts/Main.astro
|
||||
title: Deploy Your Website
|
||||
title: Deploy a Website
|
||||
---
|
||||
|
||||
> This page is based off of [Vite's](https://vitejs.dev/) well-documented [static deploy instructions](https://vitejs.dev/guide/static-deploy.html).
|
||||
|
||||
The following guides are based on some shared assumptions:
|
||||
|
||||
- You are using the default build output location (`dist/`). This location [can be changed using the `dist` configuration option](/docs/reference/configuration-reference.md).
|
||||
- You are using the default build output location (`dist/`). This location [can be changed using the `dist` configuration option](/reference/configuration-reference).
|
||||
- You are using npm. You can use equivalent commands to run the scripts if you are using Yarn or other package managers.
|
||||
- Astro is installed as a local dev dependency in your project, and you have setup the following npm scripts:
|
||||
|
||||
```json
|
||||
{
|
||||
"scripts": {
|
||||
"build": "astro build",
|
||||
"preview": "astro preview"
|
||||
"start": "astro dev",
|
||||
"build": "astro build"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
## Building The App
|
||||
|
||||
You may run `npm run build` command to build the app.
|
||||
|
@ -33,7 +35,8 @@ By default, the build output will be placed at `dist/`. You may deploy this `dis
|
|||
## GitHub Pages
|
||||
|
||||
1. Set the correct `buildOptions.site` in `astro.config.js`.
|
||||
2. Inside your project, create `deploy.sh` with the following content (with highlighted lines uncommented appropriately), and run it to deploy:
|
||||
2. Run `touch public/.nojekyll` to create a `.nojekyll` file in `public/`. This [bypasses GitHub Page's default behavior](https://github.blog/2009-12-29-bypassing-jekyll-on-github-pages/) to ignore paths prefixed with `_`.
|
||||
3. Inside your project, create `deploy.sh` with the following content (uncommenting the appropriate lines), and run it to deploy:
|
||||
|
||||
```bash{13,20,23}
|
||||
#!/usr/bin/env sh
|
||||
|
@ -55,15 +58,14 @@ By default, the build output will be placed at `dist/`. You may deploy this `dis
|
|||
git commit -m 'deploy'
|
||||
|
||||
# if you are deploying to https://<USERNAME>.github.io
|
||||
# git push -f git@github.com:<USERNAME>/<USERNAME>.github.io.git master
|
||||
# git push -f git@github.com:<USERNAME>/<USERNAME>.github.io.git main
|
||||
|
||||
# if you are deploying to https://<USERNAME>.github.io/<REPO>
|
||||
# git push -f git@github.com:<USERNAME>/<REPO>.git master:gh-pages
|
||||
# git push -f git@github.com:<USERNAME>/<REPO>.git main:gh-pages
|
||||
|
||||
cd -
|
||||
```
|
||||
|
||||
> You can also run the above script in your CI setup to enable automatic deployment on each push.
|
||||
> You can also run the above script in your CI setup to enable automatic deployment on each push.
|
||||
|
||||
### GitHub Actions
|
||||
|
||||
|
@ -120,12 +122,26 @@ TODO: We'd love an example action snippet to share here!
|
|||
|
||||
## Netlify
|
||||
|
||||
1. On [Netlify](https://netlify.com), setup up a new project from GitHub with the following settings:
|
||||
In your codebase, make sure you have a `.nvmrc` file with `v14.15.1` in it.
|
||||
|
||||
You can configure your deploy in two ways, via the Netlify website or with the `netlify.toml` file.
|
||||
|
||||
With the `netlify.toml` file, add it at the top level of your project with the following settings:
|
||||
|
||||
```toml
|
||||
[build]
|
||||
command = "npm run build"
|
||||
publish = "dist"
|
||||
```
|
||||
|
||||
Then, set up a new project on [Netlify](https://netlify.com) from your chosen Git provider.
|
||||
|
||||
If you don't want to use the `netlify.toml`, when you go to [Netlify](https://netlify.com) and set up up a new project from Git, input the following settings:
|
||||
|
||||
- **Build Command:** `astro build` or `npm run build`
|
||||
- **Publish directory:** `dist`
|
||||
|
||||
2. Hit the deploy button.
|
||||
Then hit the deploy button.
|
||||
|
||||
## Google Firebase
|
||||
|
||||
|
@ -233,8 +249,8 @@ You can deploy your Astro project with Microsoft Azure [Static Web Apps](https:/
|
|||
- Your app code pushed to [GitHub](https://github.com).
|
||||
- The [SWA Extension](https://marketplace.visualstudio.com/items?itemName=ms-azuretools.vscode-azurestaticwebapps) in [Visual Studio Code](https://code.visualstudio.com).
|
||||
|
||||
Install the extension in VS Code and navigate to your app root. Open the Static Web Apps extension, sign in to Azure, and click the '+' sign to create a new Static Web App. You will be prompted to designate which subscription key to use.
|
||||
Install the extension in VS Code and navigate to your app root. Open the Static Web Apps extension, sign in to Azure, and click the '+' sign to create a new Static Web App. You will be prompted to designate which subscription key to use.
|
||||
|
||||
Follow the wizard started by the extension to give your app a name, choose a framework preset, and designate the app root (usually `/`) and built file location `/dist`. The wizard will run and will create a GitHub action in your repo in a `.github` folder.
|
||||
Follow the wizard started by the extension to give your app a name, choose a framework preset, and designate the app root (usually `/`) and built file location `/dist`. The wizard will run and will create a GitHub action in your repo in a `.github` folder.
|
||||
|
||||
The action will work to deploy your app (watch its progress in your repo's Actions tab) and, when successfully completed, you can view your app in the address provided in the extension's progress window by clicking the 'Browse Website' button that appears when the GitHub action has run.
|
||||
The action will work to deploy your app (watch its progress in your repo's Actions tab) and, when successfully completed, you can view your app in the address provided in the extension's progress window by clicking the 'Browse Website' button that appears when the GitHub action has run.
|
||||
|
|
|
@ -29,7 +29,7 @@ export function getUser() {
|
|||
}
|
||||
|
||||
// src/index.js
|
||||
import { getUser } from './user.js';
|
||||
import {getUser} from './user.js';
|
||||
```
|
||||
|
||||
All browsers now support ESM, so Astro is able to ship this code directly to the browser during development.
|
||||
|
@ -38,7 +38,7 @@ All browsers now support ESM, so Astro is able to ship this code directly to the
|
|||
|
||||
Astro includes built-in support to build TypeScript files (`*.ts`) to JavaScript. Astro components also support TypeScript in the frontmatter script section.
|
||||
|
||||
Note that this built-in support is build only. By default, Astro does not type-check your TypeScript code.
|
||||
Note that this built-in support is build only. By default, Astro does not type-check your TypeScript code.
|
||||
|
||||
<!-- To integrate type checking into your development/build workflow, add the [@snowpack/plugin-typescript](https://www.npmjs.com/package/@snowpack/plugin-typescript) plugin. -->
|
||||
|
||||
|
@ -46,7 +46,7 @@ Note that this built-in support is build only. By default, Astro does not type-c
|
|||
|
||||
Astro includes built-in support to build JSX files (`*.jsx` & `*.tsx`) to JavaScript.
|
||||
|
||||
If you are using Preact, Astro will detect your Preact import and switch to use the Preact-style JSX `h()` function. This is all done automatically for you.
|
||||
If you are using Preact, Astro will detect your Preact import and switch to use the Preact-style JSX `h()` function. This is all done automatically for you.
|
||||
|
||||
**Note: Astro does not support JSX in `.js`/`.ts` files.**
|
||||
|
||||
|
@ -105,7 +105,7 @@ All other assets not explicitly mentioned above can be imported via ESM `import`
|
|||
const wasm = await WebAssembly.instantiateStreaming(fetch('/example.wasm'));
|
||||
```
|
||||
|
||||
Astro supports loading WASM files directly into your application using the browser's [`WebAssembly`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly) API. Read our [WASM guide](/docs/guides/wasm.md) to learn more.
|
||||
Astro supports loading WASM files directly into your application using the browser's [`WebAssembly`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly) API. Read our [WASM guide](/guides/wasm) to learn more.
|
||||
|
||||
## NPM Packages
|
||||
|
||||
|
@ -121,7 +121,7 @@ When you start up your dev server or run a new build, you may see a message that
|
|||
|
||||
## Node Builtins
|
||||
|
||||
We encourage Astro users to avoid Node.js builtins (`fs`, `path`, etc) whenever possible. Astro aims to be compatible with multiple JavaScript runtimes in the future. This includes [Deno](https://deno.land/) and [Cloudflare Workers](https://workers.cloudflare.com/) which do not support Node builtin modules such as `fs`.
|
||||
We encourage Astro users to avoid Node.js builtins (`fs`, `path`, etc) whenever possible. Astro aims to be compatible with multiple JavaScript runtimes in the future. This includes [Deno](https://deno.land/) and [Cloudflare Workers](https://workers.cloudflare.com/) which do not support Node builtin modules such as `fs`.
|
||||
|
||||
Our aim is to provide Astro alternatives to common Node.js builtins. However, no such alternatives exist today. So, if you _really_ need to use these builtin modules we don't want to stop you. Astro supports Node.js builtins using Node's newer `node:` prefix. If you want to read a file, for example, you can do so like this:
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
layout: ~/layouts/Main.astro
|
||||
title: Markdown Content
|
||||
title: Markdown
|
||||
---
|
||||
|
||||
Astro comes with out-of-the-box Markdown support powered by the expansive [remark](https://remark.js.org/) ecosystem.
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
---
|
||||
layout: ~/layouts/Main.astro
|
||||
title: Publish Components to NPM
|
||||
title: Publish a Component to NPM
|
||||
---
|
||||
|
||||
Built a great Astro component? **Publish it to [npm!](https://npmjs.com/)**
|
||||
Built a great Astro component? **Publish it to [npm!](https://npmjs.com/)**
|
||||
|
||||
Once published to npm, Astro components can be installed and used in your project like any other npm package. npm is a great way to share Astro components across projects within your team, your company, or the entire world.
|
||||
Once published to npm, Astro components can be installed and used in your project like any other npm package. npm is a great way to share Astro components across projects within your team, your company, or the entire world.
|
||||
|
||||
## Basic NPM Package Setup
|
||||
|
||||
|
@ -66,7 +66,7 @@ import Capitalize from '@example/my-components/Capitalize.astro';
|
|||
<Capitalize phrase={`Hello world`} />
|
||||
```
|
||||
|
||||
This is a less common scenario, and we only recommend it if you have good reason. Because Astro is completely rendered at build-time, there are no client-side performance concerns to our default recommendation to export your components from a single `index.js` file.
|
||||
This is a less common scenario, and we only recommend it if you have good reason. Because Astro is completely rendered at build-time, there are no client-side performance concerns to our default recommendation to export your components from a single `index.js` file.
|
||||
|
||||
To support importing by file within your package, add each file to your **package.json** `exports` map:
|
||||
|
||||
|
@ -80,4 +80,4 @@ To support importing by file within your package, add each file to your **packag
|
|||
+ "./Capitalize.astro": "./Capitalize.astro"
|
||||
}
|
||||
}
|
||||
```
|
||||
```
|
|
@ -1,26 +1,25 @@
|
|||
---
|
||||
layout: ~/layouts/Main.astro
|
||||
title: Styling
|
||||
title: Styling & CSS
|
||||
---
|
||||
|
||||
## 🖍 Quick Start
|
||||
Astro includes special handling to make writing CSS as easy as possible. Styling inside of Astro components is done by adding a `<style>` tag anywhere.
|
||||
|
||||
Styling in an Astro component is done by adding a `<style>` tag anywhere. By default, all styles are **scoped**, meaning they only apply to the current component. To create global styles, add a `:global()` wrapper around a selector (the same as if you were using [CSS Modules][css-modules]).
|
||||
By default, all Astro component styles are **scoped**, meaning they only apply to the current component. These styles are automatically extracted and optimized for you in the final build, so that you don't need to worry about style loading.
|
||||
|
||||
To create global styles, add a `:global()` wrapper around a selector (the same as if you were using [CSS Modules][css-modules]).
|
||||
|
||||
```html
|
||||
<!-- src/components/MyComponent.astro -->
|
||||
|
||||
<style>
|
||||
/* Scoped class selector within the component */
|
||||
.scoped {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/* Scoped element selector within the component */
|
||||
h1 {
|
||||
color: red;
|
||||
}
|
||||
|
||||
/* Global style */
|
||||
:global(h1) {
|
||||
font-size: 32px;
|
||||
|
@ -31,11 +30,8 @@ Styling in an Astro component is done by adding a `<style>` tag anywhere. By def
|
|||
<h1>I have both scoped and global styles</h1>
|
||||
```
|
||||
|
||||
**Tips**
|
||||
📚 Read our full guide on [Astro component syntax](/core-concepts/astro-components#css-styles) to learn more about using the `<style>` tag.
|
||||
|
||||
- `<style>` tags within `.astro` files will be extracted and optimized for you on build. So you can write CSS without worrying too much about delivery.
|
||||
- For best result, only have one `<style>` tag per-Astro component. This isn’t necessarily a limitation, but it may result in better optimization at buildtime.
|
||||
- If you want to import third-party libraries into an Astro component, you can use [Sass][sass]! In particular, [@use][sass-use] may come in handy (e.g. `@use "bootstrap/scss/bootstrap"`);
|
||||
|
||||
## Cross-Browser Compatibility
|
||||
|
||||
|
@ -60,8 +56,7 @@ All styles in Astro are automatically [**autoprefixed**](#cross-browser-compatib
|
|||
|
||||
---
|
||||
|
||||
## Using Frameworks and Libraries
|
||||
|
||||
## Frameworks and Libraries
|
||||
### 📘 React / Preact
|
||||
|
||||
`.jsx` files support both global CSS and CSS Modules. To enable the latter, use the `.module.css` extension (or `.module.scss`/`.module.sass` if using Sass).
|
||||
|
@ -132,11 +127,20 @@ Now you’re ready to write Tailwind! Our recommended approach is to create a `p
|
|||
@tailwind utilities;
|
||||
```
|
||||
|
||||
💁 As an alternative to `public/global.css`, You may also add Tailwind utilities to individual `pages/*.astro` components in `<style>` tags, but be mindful of duplication! If you end up creating multiple Tailwind-managed stylesheets for your site, make sure you’re not sending the same CSS to users over and over again in separate CSS files.
|
||||
As an alternative to `public/global.css`, You may also add Tailwind utilities to individual `pages/*.astro` components in `<style>` tags, but be mindful of duplication! If you end up creating multiple Tailwind-managed stylesheets for your site, make sure you’re not sending the same CSS to users over and over again in separate CSS files.
|
||||
|
||||
---
|
||||
### Importing from npm
|
||||
|
||||
## 📦 Bundling
|
||||
If you want to import third-party libraries into an Astro component, you can use a `<style lang="scss">` tag to enable [Sass][sass] and use the [@use][sass-use] rule.
|
||||
|
||||
```html
|
||||
<!-- Loads Boostrap -->
|
||||
<style lang="scss">
|
||||
@use "bootstrap/scss/bootstrap";
|
||||
</style>
|
||||
```
|
||||
|
||||
## Bundling
|
||||
|
||||
All CSS is minified and bundled automatically for you in running `astro build`. Without getting too in the weeds, the general rules are:
|
||||
|
||||
|
@ -148,13 +152,11 @@ We’ll be expanding our styling optimization story over time, and would love yo
|
|||
|
||||
_Note: be mindful when some page styles get extracted to the ”common” bundle, and some page styles stay on-page. For most people this may not pose an issue, but when part of your styles are bundled they technically may load in a different order and your cascade may be different. While problem isn’t unique to Astro and is present in almost any CSS bundling process, it can be unexpected if you’re not anticipating it. Be sure to inspect your final production build, and please [report any issues][issues] you may come across._
|
||||
|
||||
---
|
||||
|
||||
## 📚 Advanced Styling Architecture in Astro
|
||||
## Advanced Styling Architecture
|
||||
|
||||
Too many development setups take a hands-off approach to CSS, or at most leave you with only contrived examples that don’t get you very far. Telling developers “Use whatever styling solution you want!” is a nice thought that rarely works out in practice. Few styling approaches lend themselves to every setup. Astro is no different—certain styling approaches _will_ work better than others.
|
||||
|
||||
An example to illustrate this: Astro removes runtime JS (even the core framework if possible). Thus, depending on Styled Components for all your styles would be bad, as that would require React to load on pages where it’s not needed. Or at best, you’d get a “[FOUC][fouc]” as your static HTML is served but the user waits for JavaScript to download and execute. Or consider a second example at the opposite end of the spectrum: _BEM_. You _can_ use a completely-decoupled [BEM][bem] or [SMACSS][smacss] approach in Astro. But that’s a lot of manual maintenance you can avoid, and it leaves out a lof of convenience of [Astro components][astro-syntax].
|
||||
An example to illustrate this: Astro removes runtime JS (even the core framework if possible). Thus, depending on Styled Components for all your styles would be bad, as that would require React to load on pages where it’s not needed. Or at best, you’d get a “[FOUC][fouc]” as your static HTML is served but the user waits for JavaScript to download and execute. Or consider a second example at the opposite end of the spectrum: _BEM_. You _can_ use a completely-decoupled [BEM][bem] or [SMACSS][smacss] approach in Astro. But that’s a lot of manual maintenance you can avoid, and it leaves out a lof of convenience of [Astro components](/core-concepts/astro-components).
|
||||
|
||||
We think there’s a great middle ground between intuitive-but-slow CSS-in-JS and fast-but-cumbersome global CSS: **Hybrid Scoped + Utility CSS**. This approach works well in Astro, is performant for users, and will be the best styling solution in Astro _for most people_ (provided you’re willing to learn a little). So as a quick recap:
|
||||
|
||||
|
@ -480,7 +482,6 @@ This guide wouldn’t be possible without the following blog posts, which expand
|
|||
|
||||
Also please check out the [Stylelint][stylelint] project to whip your styles into shape. You lint your JS, why not your CSS?
|
||||
|
||||
[astro-syntax]: ./syntax.md
|
||||
[autoprefixer]: https://github.com/postcss/autoprefixer
|
||||
[bem]: http://getbem.com/introduction/
|
||||
[box-model]: https://developer.mozilla.org/en-US/docs/Learn/CSS/Building_blocks/The_box_model
|
||||
|
|
|
@ -1,60 +0,0 @@
|
|||
---
|
||||
layout: ~/layouts/Main.astro
|
||||
title: Start Here
|
||||
---
|
||||
|
||||
<img src="https://github.com/snowpackjs/astro/blob/main/assets/social/banner.png?raw=true" alt="Astro" width="100%" height="auto" >
|
||||
|
||||
## What is Astro?
|
||||
|
||||
**Astro** is a _fresh but familiar_ approach to building websites. Astro combines decades of proven performance best practices with the DX improvements of the component-oriented era.
|
||||
|
||||
With Astro, you can use your favorite JavaScript framework and automatically ship the bare-minimum amount of JavaScript—by default, it's none at all!
|
||||
|
||||
## Project Status
|
||||
|
||||
⚠️ **Astro is still an early beta, missing features and bugs are to be expected!** If you can stomach it, then Astro-built sites are production ready and several production websites built with Astro already exist in the wild. We will update this note once we get closer to a stable, v1.0 release.
|
||||
|
||||
## 🔧 Quick Start
|
||||
|
||||
> **Important**: Astro is built with [ESM modules](https://nodejs.org/api/esm.html) which are not supported in older version of Node.js. The minimum supported version is **14.16.1**.
|
||||
|
||||
```bash
|
||||
# create your project
|
||||
mkdir new-project-directory
|
||||
cd new-project-directory
|
||||
npm init astro
|
||||
|
||||
# install your dependencies
|
||||
npm install
|
||||
|
||||
# start the dev server and open your browser
|
||||
npm start
|
||||
```
|
||||
|
||||
### 🚀 Build & Deployment
|
||||
|
||||
The default Astro project has the following `scripts` in the `/package.json` file:
|
||||
|
||||
```json
|
||||
{
|
||||
"scripts": {
|
||||
"start": "astro dev",
|
||||
"build": "astro build"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
For local development, run:
|
||||
|
||||
```
|
||||
npm run start
|
||||
```
|
||||
|
||||
To build for production, run the following command:
|
||||
|
||||
```
|
||||
npm run build
|
||||
```
|
||||
|
||||
To deploy your Astro site to production, upload the contents of `/dist` to your favorite static site host.
|
|
@ -21,9 +21,9 @@ cd <project-name>
|
|||
npm init astro
|
||||
```
|
||||
|
||||
Follow the CLI instructions to install Astro with one of our official project starter templates.
|
||||
Follow the CLI instructions to install Astro with one of our official project starter templates.
|
||||
|
||||
Once completed, jump over to our [Quickstart Guide](/docs/quick-start.md#start-your-project) for a 30-second walkthrough on how to start & build your new Astro project!
|
||||
Once completed, jump over to our [Quickstart Guide](/quick-start#start-your-project) for a 30-second walkthrough on how to start & build your new Astro project!
|
||||
|
||||
## Manual Install
|
||||
|
||||
|
@ -46,7 +46,7 @@ npm init --yes
|
|||
|
||||
### Install Astro
|
||||
|
||||
If you've followed the instructions above, you should have a directory with a single `package.json` file inside of it. You can now install Astro in your project.
|
||||
If you've followed the instructions above, you should have a directory with a single `package.json` file inside of it. You can now install Astro in your project.
|
||||
|
||||
We'll use `npm` in the examples below, but you could also use `yarn` or `pnpm` if you prefer an npm alternative. If you aren't familiar with `yarn` or `pnpm`, then we strongly recommend sticking with `npm`.
|
||||
|
||||
|
@ -85,8 +85,9 @@ You can create more pages in the `src/pages` directory, and Astro will use the f
|
|||
|
||||
### Next Steps
|
||||
|
||||
Success! You're now ready to start developing! Jump over to our [Quickstart Guide](/docs/quick-start.md#start-your-project) for a 30-second walkthrough on how to start & build your new Astro project!
|
||||
Success! You're now ready to start developing! Jump over to our [Quickstart Guide](/quick-start#start-your-project) for a 30-second walkthrough on how to start & build your new Astro project!
|
||||
|
||||
📚 Learn more about Astro's project structure in our [Project Structure guide](/docs/core-concepts/project-structure.md).
|
||||
📚 Learn more about Astro's component syntax in our [Astro Components guide](/docs/core-concepts/astro-components.md).
|
||||
📚 Learn more about Astro's project structure in our [Project Structure guide](/core-concepts/project-structure).
|
||||
📚 Learn more about Astro's component syntax in our [Astro Components guide](/core-concepts/astro-components).
|
||||
📚 Learn more about Astro's file-based routing in our [Routing guide](core-concepts/astro-pages).
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
---
|
||||
layout: ~/layouts/Main.astro
|
||||
title: Data Sources / CMS
|
||||
---
|
||||
---
|
|
@ -1,4 +1,4 @@
|
|||
---
|
||||
layout: ~/layouts/Main.astro
|
||||
title: Deploy Astro
|
||||
---
|
||||
---
|
|
@ -1,4 +1,4 @@
|
|||
---
|
||||
layout: ~/layouts/Main.astro
|
||||
title: Developer Tools
|
||||
---
|
||||
---
|
|
@ -1,4 +1,4 @@
|
|||
---
|
||||
layout: ~/layouts/Main.astro
|
||||
title: State Management
|
||||
---
|
||||
---
|
|
@ -1,4 +1,4 @@
|
|||
---
|
||||
layout: ~/layouts/Main.astro
|
||||
title: Styles & CSS Libraries
|
||||
---
|
||||
---
|
|
@ -25,6 +25,8 @@ npm run build
|
|||
|
||||
To deploy your Astro site to production, upload the contents of the `/dist` folder (generated by running `npm run build`) to your favorite hosting provider.
|
||||
|
||||
[Read more about deploying Astro in the Deploy guide](/guides/deploy)
|
||||
|
||||
## Start your project
|
||||
|
||||
Go back to your command-line terminal, and run the following command in your project directory:
|
||||
|
|
|
@ -9,7 +9,7 @@ The `Astro` global is available in all contexts in `.astro` files. It has the fo
|
|||
|
||||
### `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][docs-collections].
|
||||
`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
|
||||
|
@ -65,14 +65,13 @@ const data = Astro.fetchContent('../pages/post/*.md'); // returns an array of po
|
|||
`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][docs-collections], `collection` is a prop exposed to the page with the following shape:
|
||||
When using the [Collections API](/core-concepts/collections), `collection` is a prop exposed to the page with the following shape:
|
||||
|
||||
| Name | Type | Description |
|
||||
| :------------------------ | :-------------------: | :-------------------------------------------------------------------------------------------------------------------------------- |
|
||||
|
@ -103,15 +102,15 @@ export async function createCollection() {
|
|||
}
|
||||
```
|
||||
|
||||
When using the [Collections API][docs-collections], `createCollection()` is an async function that returns an object of the following shape:
|
||||
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][rss] | Optional: generate an RSS 2.0 feed from this collection ([docs][rss]). |
|
||||
| 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._
|
||||
|
||||
|
@ -177,6 +176,4 @@ export default function () {
|
|||
```
|
||||
|
||||
[canonical]: https://en.wikipedia.org/wiki/Canonical_link_element
|
||||
[config]: ../README.md#%EF%B8%8F-configuration
|
||||
[docs-collections]: ./collections.md
|
||||
[rss]: #-rss-feed
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
layout: ~/layouts/Main.astro
|
||||
title: Astro Builtin Components
|
||||
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';`.
|
||||
|
@ -16,10 +16,10 @@ import { Markdown } from 'astro/components';
|
|||
</Markdown>
|
||||
```
|
||||
|
||||
See our [Markdown Guide](/docs/guides/markdown-content.md) for more info.
|
||||
|
||||
See our [Markdown Guide](/guides/markdown-content) for more info.
|
||||
<!-- TODO: We should move some of the specific component info here. -->
|
||||
|
||||
|
||||
## `<Prism />`
|
||||
|
||||
```astro
|
||||
|
|
|
@ -7,7 +7,7 @@ title: CLI Reference
|
|||
|
||||
### `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](../README.md##%EF%B8%8F-configuration)).
|
||||
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](./dev.md) docs for more information on how the dev server works.
|
||||
|
||||
|
@ -21,6 +21,7 @@ Specifies should port to run on. Defaults to `3000`.
|
|||
|
||||
Builds your site for production.
|
||||
|
||||
|
||||
## Global Flags
|
||||
|
||||
### `--config path`
|
||||
|
|
|
@ -27,4 +27,4 @@ export default {
|
|||
|
||||
## 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.
|
||||
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.
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
layout: ~/layouts/Main.astro
|
||||
title: UI Renderers
|
||||
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.
|
||||
|
@ -55,10 +55,13 @@ Additionally, this entrypoint can define a [Snowpack plugin](https://www.snowpac
|
|||
export default {
|
||||
name: '@astrojs/renderer-xxx', // the renderer name
|
||||
client: './client.js', // relative path to the client entrypoint
|
||||
server: './server.js', // relative path to the server 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.
|
||||
};
|
||||
```
|
||||
|
||||
|
@ -153,5 +156,3 @@ export default (element) => {
|
|||
};
|
||||
};
|
||||
```
|
||||
|
||||
[astro-config]: ./config.md
|
||||
|
|
Loading…
Reference in a new issue