The web framework that scales with you — Build fast content sites, powerful web applications, dynamic server APIs, and everything in-between ️ Star to support our work!
Find a file
Matthew Phillips ad9c3b1d8d
Parse inner JSX as Astro (#67)
* Parse inner JSX as Astro

This completes the compiler changes, updating the parser so that it parses inner "JSX" as Astro. It does this by finding the start and end of HTML tags and feeds that back into the parser.

The result is a structure like this:

```
{
  type: 'MustacheTag',
  expression: [
    {
      type: 'Expression',
      codeStart: 'colors.map(color => (',
      codeEnd: '}}'
      children: [ {
        type: 'Fragment',
        children: [ {
          type: 'Element',
          name: 'div'
        } ]
      } ]
    }
  ]
}
```

There is a new Node type, `Expression`.  Note that `MustacheTag` remains in the tree, all it contains is an Expression though. I could spend some time trying to remove it, there's just a few places that expect it to exist.

* Update import to the transform

* Transform prism components into expressions
2021-04-09 14:09:13 -04:00
.github Extract Astro styles to external stylesheets (#43) 2021-03-31 13:04:18 -06:00
.vscode Scaffold language server (#25) 2021-03-25 10:38:17 -05:00
astro-prism Add support for syntax highlighting of code blocks (#65) 2021-04-08 15:17:00 -04:00
components Add support for syntax highlighting of code blocks (#65) 2021-04-08 15:17:00 -04:00
examples Add support for syntax highlighting of code blocks (#65) 2021-04-08 15:17:00 -04:00
src Parse inner JSX as Astro (#67) 2021-04-09 14:09:13 -04:00
test Parse inner JSX as Astro (#67) 2021-04-09 14:09:13 -04:00
vscode Scaffold language server (#25) 2021-03-25 10:38:17 -05:00
www Add support for syntax highlighting of code blocks (#65) 2021-04-08 15:17:00 -04:00
.eslintignore Annoying Lint PR #2 (#47) 2021-04-01 10:25:28 -06:00
.eslintrc.cjs Blog Support 1/3: Data fetching (#62) 2021-04-06 15:54:55 -06:00
.gitignore Scaffold language server (#25) 2021-03-25 10:38:17 -05:00
.prettierrc.json Annoying Lint PR™ (#3) 2021-03-16 12:37:45 -06:00
astro.mjs Add a proper cli 2021-03-15 15:26:23 -04:00
LICENSE Bring compiler into Astro (#4) 2021-03-16 16:08:11 -04:00
package-lock.json Blog Support 1/3: Data fetching (#62) 2021-04-06 15:54:55 -06:00
package.json Add support for syntax highlighting of code blocks (#65) 2021-04-08 15:17:00 -04:00
README.md Blog Support 1/3: Data fetching (#62) 2021-04-06 15:54:55 -06:00
snowpack-plugin.cjs Extract Astro styles to external stylesheets (#43) 2021-03-31 13:04:18 -06:00
tsconfig.json Add type declarations (#59) 2021-04-02 21:01:57 -06:00

👩‍🚀 Astro

A next-generation static-site generator with partial hydration. Use your favorite JS framework and ship bare-minimum JS (or none at all!).

🔧 Setup

npm install astro

🧞 Development

Add a dev npm script to your /package.json file:

{
  "scripts": {
    "dev": "astro dev ."
  }
}

Then run:

npm run dev

⚙️ Configuration

To configure Astro, add a astro.config.mjs file in the root of your project. All of the options can be omitted. Here are the defaults:

export default {
  /** Where to resolve all URLs relative to. Useful if you have a monorepo project. */
  projectRoot: '.',
  /** Path to Astro components, pages, and data */
  astroRoot: './astro',
  /** When running `astro build`, path to final static output */
  dist: './_site',
  /** A folder of static files Astro will copy to the root. Useful for favicons, images, and other files that dont need processing. */
  public: './public',
  /** Extension-specific handlings */
  extensions: {
    /** Set this to "preact" or "react" to determine what *.jsx files should load */
    '.jsx': 'react',
  },
};

💧 Partial Hydration

By default, Astro outputs zero client-side JS. If you'd like to include an interactive component in the client output, you may use any of the following techniques.

  • <MyComponent /> will render an HTML-only version of MyComponent (default)
  • <MyComponent:load /> will render MyComponent on page load
  • <MyComponent:idle /> will use requestIdleCallback() to render MyComponent as soon as main thread is free
  • <MyComponent:visible /> will use an IntersectionObserver to render MyComponent when the element enters the viewport

💅 Styling

If youve used Sveltes styles before, Astro works almost the same way. In any .astro file, start writing styles in a <style> tag like so:

<style>
  .scoped {
    font-weight: bold;
  }
</style>

<div class="scoped">Im a scoped style</div>

👓 Sass

Astro also supports Sass out-of-the-box; no configuration needed:

<style lang="scss">
  @use "../tokens" as *;

  .title {
    color: $color.gray;
  }
</style>

<h1 class="title">Title</h1>

Supports:

  • lang="scss": load as the .scss extension
  • lang="sass": load as the .sass extension (no brackets; indent-style)

🦊 Autoprefixer

We also automatically add browser prefixes using Autoprefixer. By default, Astro loads the default values, but you may also specify your own by placing a Browserslist file in your project root.

🍃 Tailwind

Astro can be configured to use Tailwind easily! Install the dependencies:

npm install @tailwindcss/jit tailwindcss

And also create a tailwind.config.js in your project root:

module.exports = {
  // your options here
}

Note: a Tailwind config file is currently required to enable Tailwind in Astro, even if you use the default options.

Then write Tailwind in your project just like youre used to:

<style>
  @tailwind base;
  @tailwind components;
  @tailwind utilities;
</style>

🍱 Collections (beta)

Astros Collections API is useful for grabbing collections of content. Currently only *.md files are supported.

🔽 Markdown
// pages/blog.astro
---
import PostPreview from '../components/PostPreview.astro';

const blogPosts = import.meta.collections('./post/*.md');
---

<main>
  <h1>Blog Posts</h1>
  {blogPosts.map((post) => (
    <PostPreview post={post} />
  )}
</main>

This will load all markdown files located in /pages/post/*.md, compile them into an array, then expose them to the page.

If you were to inspect the array, youd find the following schema:

const blogPosts = [
  {
    content: string, // Markdown converted to HTML
    // all other frontmatter data
  },
  // …
];
🧑‍🍳 Advanced usage

All of the following options are supported under the 2nd parameter of import.meta.collections():

const collection = import.meta.collections('./post/*.md', {
  /** If `page` is omitted, all results are returned */
  page: 1, // ⚠️ starts at 1, not 0
  /** How many items should be returned per-page (ignored if `page` is missing; default: 25) */
  perPage: 25,
  /** How items should be sorted (default: no sort) */
  sort(a, b) {
    return new Date(b.date) - new Date(a.date); // sort newest first, by `date` in frontmatter
  }
  /** Should items be filtered by their frontmatter data? */
  filter(post) {
    return post.tag === 'movie'; // (optional) only return posts tagged "movie"
  }
});

🚀 Build & Deployment

Add a build npm script to your /package.json file:

{
  "scripts": {
    "dev": "astro dev .",
    "build": "astro build ."
  }
}

Then run:

npm run build

Now upload the contents of /_site_ to your favorite static site host.