Compare commits

...

89 commits

Author SHA1 Message Date
993c085952 expose file url to markdown renderer 2023-10-11 11:46:58 -05:00
Alexander Niebuhr
3f231cefed
port https://github.com/withastro/docs/pull/4980 (#8799) 2023-10-11 07:06:20 +02:00
lilnasy
a8b979ef40 [ci] format 2023-10-10 16:40:46 +00:00
Arsh
bd5aa1cd35
fix(transitions router): no-op on the server (#8771)
* fix(transitions router): no-op on the server

* factor out onPopState

* add e2e test case

* Apply suggestions from code review

Co-authored-by: Martin Trapp <94928215+martrapp@users.noreply.github.com>

* use supportsViewTransitions

* add changeset

* warn on navigate() use during ssr

* switch supportsViewTransitions to import.meta.env

* correct typo

* bring back import.meta.env

* !import.meta.env.SSR -> inBrowser

* Apply suggestions from code review

Co-authored-by: Martin Trapp <94928215+martrapp@users.noreply.github.com>

* Apply suggestions from code review

Co-authored-by: Martin Trapp <94928215+martrapp@users.noreply.github.com>

---------

Co-authored-by: Martin Trapp <94928215+martrapp@users.noreply.github.com>
2023-10-10 22:08:35 +05:30
alexanderniebuhr
03e6979c28 [ci] format 2023-10-10 16:11:20 +00:00
Mikkel Ricafrente
75781643a2
fix(cloudflare): runtime types for Cloudflare caches (#8782)
* fix cachestorage reference in cloudflare integration

* add cachestorage to serverdirectorymode

* add changeset

* remove global caches type

* update unlucky-avocados-brake.md
2023-10-10 18:08:17 +02:00
Houston (Bot)
9cd6a6657b
[ci] release (#8768)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-10-10 22:30:52 +08:00
Arsh
c071458257
chore: removed adapters cleanup (#8726)
* update ci, readme, comments, remote workspaces

* fix hosted test fixture

* keep adapter config typedocs
2023-10-10 19:36:35 +05:30
Alexander Niebuhr
0ab6bad7df
fix(cloudflare): esbuild settings for cloudflare (#8788)
---------

Co-authored-by: Jonathan Dunlap <595843+jadbox@users.noreply.github.com>
2023-10-10 09:16:32 +02:00
alexanderniebuhr
90d70eb7c4 [ci] format 2023-10-09 17:16:02 +00:00
Jonathan Dunlap
054c5c6447
fix(cloudflare): support for 'cloudflare:*' imports (#8766)
* chore: add 'cloudflare:sockets' to external list

* chore: add Changeset

* patch: wildcard cloudflare packages

* chore: updated Readme for cloudflare module support

* Update .changeset/heavy-elephants-tan.md

Co-authored-by: Sarah Rainsberger <sarah@rainsberger.ca>

* Update packages/integrations/cloudflare/README.md

Co-authored-by: Sarah Rainsberger <sarah@rainsberger.ca>

---------

Co-authored-by: Sarah Rainsberger <sarah@rainsberger.ca>
Co-authored-by: Alexander Niebuhr <alexander@nbhr.io>
2023-10-09 19:13:46 +02:00
ematipico
7ea27f6319 [ci] format 2023-10-09 16:00:28 +00:00
Arsh
c4a7ec4255
fix(windows): ensure drive letter is uppercase (#8741) 2023-10-09 16:58:09 +01:00
bluwy
a0dc79b946 [ci] format 2023-10-09 14:23:53 +00:00
Florian Lefebvre
160d1cd755
feat(tailwind): create a tailwind.config.mjs file by default (#8638) 2023-10-09 22:21:26 +08:00
Martin Trapp
29cdfa0248
Fix transition attributes on islands (#8776)
* Fix transition attributes on islands

* Incorporate comments from review
2023-10-09 16:19:46 +02:00
Martin Trapp
c24f70d916
Fix flickering during view transitions (#8772)
* Fix for #8711

* more descriptive changeset

* chores, while we are at it ...
2023-10-09 16:15:23 +02:00
Bjorn Lu
33d0be50be
Fix snapshot release permissions (#8777) 2023-10-09 20:47:06 +08:00
Bjorn Lu
93b092266f
Make CSS chunk names less confusing (#8754) 2023-10-09 17:29:28 +08:00
Makito
eaed844ea8
fix(assets): add the missing await to getHTMLAttributes (#8773) 2023-10-07 21:22:47 +02:00
Martin Trapp
30de324361
Revert fix #8472 (#8767) 2023-10-06 23:17:27 +02:00
Matthew Phillips
2262814a92 Give snapshot releases the issues: write permission 2023-10-06 16:11:29 -04:00
Matthew Phillips
f9131003d7 Give the snapshot release the right permissions 2023-10-06 16:00:29 -04:00
Matthew Phillips
d51cf5e707 Snapshot release: prevent setting output 2023-10-06 15:50:36 -04:00
Matthew Phillips
e5e6cf16eb Add debugging information on preview releases 2023-10-05 14:14:05 -04:00
Matthew Phillips
41f93e0ccb Print the publish output when it fails 2023-10-05 13:58:03 -04:00
Bjorn Lu
4e5cafa5d2
Fix git tag release (#8752) 2023-10-05 18:45:41 +08:00
Bjorn Lu
ec82e73efa
Fix provenance release (#8749) 2023-10-05 18:29:36 +08:00
Houston (Bot)
584d6f0680
[ci] release (#8738)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-10-05 11:10:06 +01:00
Jacob Lamb
78adbc4433
Update Netlify SSR link (#8700) 2023-10-05 07:18:45 +01:00
Nate Moore
d78806dfe0
fix(#8746): improve error message for dynamic component usage (#8747) 2023-10-04 15:07:21 -05:00
Bjorn Lu
aa265d7302
Remove unused CSS output files when inlined (#8743) 2023-10-04 21:18:39 +08:00
bluwy
b18d4bf3b1 [ci] format 2023-10-04 10:31:04 +00:00
Arsh
21e0757ea2
chore: remove undici polyfill (#8729) 2023-10-04 18:28:36 +08:00
bluwy
272ad45958 [ci] format 2023-10-04 10:26:21 +00:00
Chris
21f4826576
Fixes: Shiki syntax highlighting adds is:raw attribute to the HTML output (#8715)
Co-authored-by: Emanuele Stoppa <my.burning@gmail.com>
2023-10-04 18:23:58 +08:00
Kobe Ruado
71618f4074
Fix markdown rehype plugin example (#8733) 2023-10-04 17:55:02 +08:00
natemoo-re
240d8ff7c9 [ci] format 2023-10-03 21:00:07 +00:00
Nate Moore
357270f2a3
Improve astro info compatability (#8730)
* Improve `astro info` compatability

* Update packages/astro/src/cli/info/index.ts

Co-authored-by: Arsh <69170106+lilnasy@users.noreply.github.com>

* chore: add changeset

* feat(info): add copy to clipboard support on Unix machines with xclip installed

---------

Co-authored-by: Arsh <69170106+lilnasy@users.noreply.github.com>
2023-10-03 15:57:31 -05:00
Florian Lefebvre
f277ba8b70
feat: expose partytown types (close #8723) (#8740) 2023-10-03 23:16:49 +08:00
Emanuele Stoppa
6f60da805e
feat: add provenance to packages (#8737) 2023-10-03 15:25:25 +01:00
Bjorn Lu
d1c75fe158
Fix tsconfig.json update causing the server to crash (#8736) 2023-10-03 14:36:38 +01:00
Genteure
f9477aade1
fix: typo in error deprecation message (#8708)
Co-authored-by: Alexander Niebuhr <alexander@nbhr.io>
2023-10-02 18:36:15 +02:00
Houston (Bot)
78fda5c3ec
[ci] release (#8722)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-10-02 23:55:56 +08:00
Bjorn Lu
455af3235b
Fix CSS styles on windows (#8724) 2023-10-02 23:17:34 +08:00
Ray
6db2687ef0
fix(deno): link to adapter repo (#8712) 2023-10-02 16:33:24 +02:00
alexanderniebuhr
5fb6a266f8 [ci] format 2023-10-02 14:08:47 +00:00
Alexander Niebuhr
3dd65bf889
feat(cloudflare): add local mockings for CF bindings (#8655)
* feat(cloudflare): add D1 database binding

* feat(cloudflare): add local mocking for R2 bindings (#8656)

* feat(cloudflare): add local mocking for KV bindings (#8657)

* feat(cloudflare): add local mocking for Caches bindings (#8664)

* feat(cloudflare): add local mocking for DO bindings (#8690)

---------

Co-authored-by: Sarah Rainsberger <sarah@rainsberger.ca>
2023-10-02 16:04:57 +02:00
matthewp
22fae5211a [ci] format 2023-10-02 12:54:01 +00:00
Matthew Phillips
4c2bec681b
Fixes View transition styles being missing when component used multiple times (#8710) 2023-10-02 08:51:53 -04:00
Houston (Bot)
a067c2a2c7
[ci] release (#8699)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-10-02 16:34:57 +08:00
Alexander Niebuhr
0b22bb9af4
fix(cloudflare): broken link in docs (#8709) 2023-09-30 06:49:04 +02:00
Erika
47ea310f01
feat: resolve images through the file systems on applicable runtimes (#8698)
* feat: add a node image endpoint

* test: fix
2023-09-29 23:14:40 +02:00
Erika
db83237dd3
refactor(markdown): Move astro:assets-specific code out of the main Vite plugin (#8704) 2023-09-29 23:14:09 +02:00
Martin Trapp
148b5b8769
Fix preloading stylesheets in view transitions (#8707)
* Fix preload of stylesheets (VT)

* Fix preload of stylesheets (VT)
2023-09-29 20:03:19 +02:00
Bjorn Lu
345808170f
Fix duplicated Astro and Vite injected styles (#8706) 2023-09-29 21:55:46 +08:00
Bjorn Lu
31c59ad8b6
Fix hydration on slow connection (#8680) 2023-09-29 21:54:46 +08:00
Dario Piotrowicz
c3572fd5e0
fix(cloudflare): target es2022 instead of es2020 to fix esbuild incompatibility issues (#8682)
* fix(cloudflare): target es2022 instead of es2020 to fix esbuild incompatibility issues

* add changeset

* update changeset

* fix(cloudflare): change build target to es2022

---------

Co-authored-by: Alexander Niebuhr <alexander@nbhr.io>
2023-09-28 20:56:01 +02:00
Alexander Niebuhr
77d37853cb
fix(cloudflare): sneaky docs (#8694)
* fix(cloudflare): sneaky docs

* resolve docs review comments

Co-authored-by: Sarah Rainsberger <sarah@rainsberger.ca>

* resolve docs review comments

Co-authored-by: Sarah Rainsberger <sarah@rainsberger.ca>

---------

Co-authored-by: Sarah Rainsberger <sarah@rainsberger.ca>
2023-09-28 20:26:47 +02:00
Matthew Phillips
eb530e9b61
Remove the Deno example (#8697) 2023-09-28 14:17:46 -04:00
Houston (Bot)
2d33b9362d
[ci] release (#8695)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-09-28 14:12:22 -04:00
Matthew Phillips
2167ffd72f
Revert "[ci] release (#8671)" (#8696)
This reverts commit eada8ab8fa.
2023-09-28 13:57:54 -04:00
Matthew Phillips
0ba32e4402 Adds a stub version number for the old netlify adapter 2023-09-28 13:27:57 -04:00
lilnasy
c4c616c0a5 [ci] format 2023-09-28 17:19:21 +00:00
Arsh
cfd895d877
fix(rerouting): check that the new route is different (#8648)
* fix(rerouting): check that the new route is different

* add tests

* changeset grammar
2023-09-28 22:46:15 +05:30
Houston (Bot)
eada8ab8fa
[ci] release (#8671)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Matthew Phillips <matthew@skypack.dev>
2023-09-28 13:14:13 -04:00
matthewp
3c93476078 [ci] format 2023-09-28 16:23:05 +00:00
Matthew Phillips
824dd4670a
Support content collections with % in filename (#8684)
* Support content collections with % in filename

* Add changeset

* Unused eslint thing

* Update packages/astro/src/core/build/static-build.ts

Co-authored-by: Alexander Niebuhr <alexander@nbhr.io>

---------

Co-authored-by: Alexander Niebuhr <alexander@nbhr.io>
2023-09-28 12:20:25 -04:00
alexanderniebuhr
0e35457c0f [ci] format 2023-09-28 16:07:09 +00:00
Alexander Niebuhr
f6ba533df6
chore(cloudflare): refactor structure, optimize patterns (#8654)
---------

Co-authored-by: Sarah Rainsberger <sarah@rainsberger.ca>
Co-authored-by: 100gle <loogle.space@gmail.com>
2023-09-28 18:04:49 +02:00
Arsh
23e7b259eb
chore(ci): pin CI Node version to 18.17.1 (#8693)
* chore(ci): pin E2E Node version to 18.17.1

* pin for the "test" as well

* ...for windows, not ubuntu

* ...for windows, not macos
2023-09-28 20:49:45 +05:30
ElianCodes
8617259fc9 [ci] format 2023-09-28 13:50:31 +00:00
Elian ☕️
ec249f7a98
update all the readme's for expressive code (#8691)
Co-authored-by: HiDeoo <HiDeoo@users.noreply.github.com>
Co-authored-by: Genteure <Genteure@users.noreply.github.com>
Co-authored-by: Bryce Russell <brycetrussell@gmail.com>
Co-authored-by: Reuben Tier <TheOtterlord@users.noreply.github.com>
Co-authored-by: Hippo <hippotastic@users.noreply.github.com>
Co-authored-by: Sarah Rainsberger <sarah@rainsberger.ca>
Co-authored-by: Kevin Zuniga Cuellar <kevinzunigacuellar@users.noreply.github.com>
2023-09-28 15:48:03 +02:00
ElianCodes
0ab19ba615 [ci] format 2023-09-28 12:43:03 +00:00
Elian ☕️
e9b77cbf19
Update codesample for Alpine README (#8689)
Co-authored-by: HiDeoo <HiDeoo@users.noreply.github.com>
Co-authored-by: Genteure <Genteure@users.noreply.github.com>
Co-authored-by: Bryce Russell <brycetrussell@gmail.com>
Co-authored-by: Reuben Tier <TheOtterlord@users.noreply.github.com>
Co-authored-by: Hippo <hippotastic@users.noreply.github.com>
2023-09-28 14:40:08 +02:00
Adit Sachde
f5c617e3a3
Match the .well-known directory when generating routes.json (#7776)
* Match the .well-known directory when generating routes.json

* add changeset

* Update .changeset/clean-planets-retire.md

---------

Co-authored-by: Emanuele Stoppa <my.burning@gmail.com>
Co-authored-by: Erika <3019731+Princesseuh@users.noreply.github.com>
2023-09-27 18:34:29 -04:00
matthewp
c0708c921c [ci] format 2023-09-27 22:21:43 +00:00
Arsh
408b50c5ea
fix(redirects): attempt to get only params in dev mode (#8647)
* fix(redirects): attempt to get only params in dev mode

* fixtures/ssr-redirect => fixtures/redirects

* add tests

* Update pnpm-lock.yaml
2023-09-27 18:19:06 -04:00
Michaili K
e797b68160
Fix assets not getting optimized when outDir is outside the CWD (#8670)
* Fix assets not getting optimized when `outDir` is outside the CWD

* Add missing import

* Add changeset

* Fix import, again.

* Use getOutDirWithinCwd in the serverRoot declaration
2023-09-27 18:18:36 -04:00
Matthew Phillips
87d5b841af
New code (#8559) 2023-09-27 17:06:11 -04:00
Matthew Phillips
4ed410db50
Remove Netlify adapter from core (#8574)
* New link

* More explicit

* Add placeholder package.json

* lockfile

* add keyworkds
2023-09-27 16:48:26 -04:00
matthewp
a10a798c18 [ci] format 2023-09-27 19:25:02 +00:00
Matthew Phillips
e6be2d8146
Add View Transitions announcer (#8621)
* Add View Transitions announcer

* fix astro check

* Append the text in a setTimeout

* Use 60 for the timeout

* Add comment on magic number

* Add a changeset

* Update .changeset/small-rules-relax.md

Co-authored-by: Sarah Rainsberger <sarah@rainsberger.ca>

* Bring back announce logic

* Remove mention of env file

---------

Co-authored-by: Sarah Rainsberger <sarah@rainsberger.ca>
2023-09-27 15:21:56 -04:00
delucis
5121740de7 [ci] format 2023-09-27 19:19:41 +00:00
Chris Swithinbank
9b0114c7d3
Support integrations added in updateConfig() in astro:config:setup (#8672)
Co-authored-by: Sarah Rainsberger <sarah@rainsberger.ca>
2023-09-27 21:17:27 +02:00
Bjorn Lu
e8495c853b
Fix logLevel passed to Vite build (#8678) 2023-09-27 22:30:30 +08:00
martrapp
aad756297c [ci] format 2023-09-27 13:33:07 +00:00
Martin Trapp
63bc37f2b6
API for clientside router (#8571)
* refactored CSR into goto() function

* first refectoring for router API

* added test

* added comments to fixture

* rename + preliminary changeset

* changeset: now 'minor' and featuring Mathew's example from the docs

* moved for simpler diff

* update after #8617

* fixed ts-errors

* more comprehensible handling of intra-page state

* sync with main

* synch from next_tm
2023-09-27 15:30:13 +02:00
Nolan Lawson
9fe4b95969
fix: print image path for NoImageMetadata (#8666) 2023-09-26 21:51:57 +08:00
367 changed files with 87471 additions and 6526 deletions

View file

@ -1,8 +0,0 @@
FROM gitpod/workspace-node
# Install latest pnpm
RUN curl -fsSL https://get.pnpm.io/install.sh | SHELL=`which bash` bash -
# Install deno in gitpod
RUN curl -fsSL https://deno.land/x/install/install.sh | sh
RUN /home/gitpod/.deno/bin/deno completions bash > /home/gitpod/.bashrc.d/90-deno && echo 'export DENO_INSTALL="/home/gitpod/.deno"' >> /home/gitpod/.bashrc.d/90-deno && echo 'export PATH="$DENO_INSTALL/bin:$PATH"' >> /home/gitpod/.bashrc.d/90-deno

View file

@ -0,0 +1,5 @@
---
'astro': patch
---
Fixed an issue where the transitions router did not work within framework components.

View file

@ -0,0 +1,5 @@
---
'@astrojs/cloudflare': patch
---
fixes `AdvancedRuntime` & `DirectoryRuntime` types to work woth Cloudflare caches

View file

@ -6,10 +6,6 @@ RUN npm install -g @playwright/test
# Install latest pnpm
RUN npm install -g pnpm
# Install deno
ENV DENO_INSTALL=/usr/local
RUN curl -fsSL https://deno.land/x/install/install.sh | sh
RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
&& curl -sSL https://dl.google.com/linux/direct/google-chrome-stable_current_$(dpkg --print-architecture).deb -o /tmp/chrome.deb \
&& apt-get -y install /tmp/chrome.deb

View file

@ -1,34 +0,0 @@
{
"name": "Deno",
"build": {
"dockerfile": "../examples.deno.Dockerfile"
},
"workspaceFolder": "/workspaces/astro/examples/deno",
"portsAttributes": {
"4321": {
"label": "Application",
"onAutoForward": "openPreview"
}
},
"forwardPorts": [4321],
"postCreateCommand": "pnpm install && cd /workspaces/astro && pnpm run build",
"waitFor": "postCreateCommand",
"postAttachCommand": {
"Server": "pnpm start --host"
},
"customizations": {
"codespaces": {
"openFiles": ["src/pages/index.astro"]
},
"vscode": {
"extensions": ["astro-build.astro-vscode", "esbenp.prettier-vscode"]
}
}
}

View file

@ -1,10 +0,0 @@
FROM mcr.microsoft.com/devcontainers/javascript-node:0-18
# Install latest pnpm
RUN npm install -g pnpm
# Install deno
ENV DENO_INSTALL=/usr/local
RUN curl -fsSL https://deno.land/x/install/install.sh | sh
COPY example-welcome-message.txt /usr/local/etc/vscode-dev-containers/first-run-notice.txt

View file

@ -113,7 +113,7 @@ jobs:
- os: macos-latest
NODE_VERSION: 18
- os: windows-latest
NODE_VERSION: 18
NODE_VERSION: 18.17.1
fail-fast: false
env:
NODE_VERSION: ${{ matrix.NODE_VERSION }}
@ -133,11 +133,6 @@ jobs:
node-version: ${{ matrix.NODE_VERSION }}
cache: "pnpm"
- name: Use Deno
uses: denoland/setup-deno@v1
with:
deno-version: v1.35.0
- name: Install dependencies
run: pnpm install
@ -155,7 +150,7 @@ jobs:
strategy:
matrix:
OS: [ubuntu-latest, windows-latest]
NODE_VERSION: [18]
NODE_VERSION: [18.17.1]
fail-fast: false
env:
NODE_VERSION: ${{ matrix.NODE_VERSION }}

View file

@ -22,6 +22,9 @@ jobs:
name: Changelog PR or Release
if: ${{ github.repository_owner == 'withastro' }}
runs-on: ubuntu-latest
permissions:
contents: write
id-token: write
steps:
- uses: actions/checkout@v3

View file

@ -19,6 +19,11 @@ jobs:
name: Create a snapshot release of a pull request
if: ${{ github.repository_owner == 'withastro' && github.event.issue.pull_request && startsWith(github.event.comment.body, '!preview') }}
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write
issues: write
pull-requests: write
steps:
- name: "Check if user has admin access (only admins can publish snapshot releases)."
uses: "lannonbr/repo-permission-check-action@2.0.0"
@ -81,6 +86,8 @@ jobs:
id: publish
run: |
pnpm run release --tag next--${{ steps.getSnapshotName.outputs.result }} > publish.output.txt 2>&1
echo "Release complete"
cat publish.output.txt
echo ::set-output name=result::`cat publish.output.txt`
env:
# Needs access to publish to npm

View file

@ -11,8 +11,6 @@ env:
VERCEL_ORG_ID: ${{ secrets.VERCEL_TEST_ORG_ID }}
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_TEST_PROJECT_ID }}
VERCEL_TOKEN: ${{ secrets.VERCEL_TEST_TOKEN }}
NETLIFY_SITE_ID: ${{ secrets.NETLIFY_TEST_SITE_ID }}
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_TEST_AUTH_TOKEN }}
FORCE_COLOR: true
jobs:
@ -35,21 +33,19 @@ jobs:
- name: Install dependencies
run: pnpm install
- name: Install Hosts CLIs
run: pnpm install --global netlify-cli vercel
- name: Build Astro
run: pnpm turbo build --filter astro --filter @astrojs/vercel
- name: Deploy Vercel
- name: Build test project
working-directory: ./packages/integrations/vercel/test/hosted/hosted-astro-project
run:
pnpm run build
vercel --prod --prebuilt
- name: Deploy Netlify
working-directory: ./packages/integrations/netlify/test/hosted/hosted-astro-project
- name: Deploy to Vercel
working-directory: ./packages/integrations/vercel/test/hosted/hosted-astro-project
run:
pnpm run build
netlify deploy --prod
pnpm dlx vercel --prod --prebuilt
- name: Test both hosts
- name: Test
run:
pnpm run test:e2e:hosts

View file

@ -1,6 +1,4 @@
---
image:
file: .Dockerfile
# Commands to start on workspace startup
tasks:
- before: |

View file

@ -3,6 +3,9 @@
# Convert context URL to an array
mapfile -t CONTEXT_URL_ITEMS < <(echo "$GITPOD_WORKSPACE_CONTEXT_URL" | tr '/' '\n')
# Install latest pnpm
curl -fsSL https://get.pnpm.io/install.sh | SHELL=`which bash` bash -
# Check if Gitpod started from a specific example directory in the repository
if [ "${CONTEXT_URL_ITEMS[7]}" = "examples" ]; then
EXAMPLE_PROJECT=${CONTEXT_URL_ITEMS[8]}

View file

@ -52,8 +52,6 @@ Join us on [Discord](https://astro.build/chat) to meet other maintainers. We'll
| [@astrojs/svelte](packages/integrations/svelte) | [![astro version](https://img.shields.io/npm/v/@astrojs/svelte.svg?label=%20)](packages/integrations/svelte/CHANGELOG.md) |
| [@astrojs/vue](packages/integrations/vue) | [![astro version](https://img.shields.io/npm/v/@astrojs/vue.svg?label=%20)](packages/integrations/vue/CHANGELOG.md) |
| [@astrojs/lit](packages/integrations/lit) | [![astro version](https://img.shields.io/npm/v/@astrojs/lit.svg?label=%20)](packages/integrations/lit/CHANGELOG.md) |
| [@astrojs/deno](packages/integrations/deno) | [![astro version](https://img.shields.io/npm/v/@astrojs/deno.svg?label=%20)](packages/integrations/deno/CHANGELOG.md) |
| [@astrojs/netlify](packages/integrations/netlify) | [![astro version](https://img.shields.io/npm/v/@astrojs/netlify.svg?label=%20)](packages/integrations/netlify/CHANGELOG.md) |
| [@astrojs/node](packages/integrations/node) | [![astro version](https://img.shields.io/npm/v/@astrojs/node.svg?label=%20)](packages/integrations/node/CHANGELOG.md) |
| [@astrojs/vercel](packages/integrations/vercel) | [![astro version](https://img.shields.io/npm/v/@astrojs/vercel.svg?label=%20)](packages/integrations/vercel/CHANGELOG.md) |
| [@astrojs/cloudflare](packages/integrations/cloudflare) | [![astro version](https://img.shields.io/npm/v/@astrojs/cloudflare.svg?label=%20)](packages/integrations/cloudflare/CHANGELOG.md) |

View file

@ -11,6 +11,6 @@
"astro": "astro"
},
"dependencies": {
"astro": "^3.1.4"
"astro": "^3.2.4"
}
}

View file

@ -11,9 +11,9 @@
"astro": "astro"
},
"dependencies": {
"@astrojs/mdx": "^1.1.0",
"@astrojs/mdx": "^1.1.1",
"@astrojs/rss": "^3.0.0",
"@astrojs/sitemap": "^3.0.0",
"astro": "^3.1.4"
"@astrojs/sitemap": "^3.0.1",
"astro": "^3.2.4"
}
}

View file

@ -15,7 +15,7 @@
],
"scripts": {},
"devDependencies": {
"astro": "^3.1.4"
"astro": "^3.2.4"
},
"peerDependencies": {
"astro": "^2.0.0-beta.0"

View file

@ -1 +0,0 @@
FROM node:18-bullseye

View file

@ -1,4 +0,0 @@
{
"recommendations": ["astro-build.astro-vscode"],
"unwantedRecommendations": []
}

View file

@ -1,11 +0,0 @@
{
"version": "0.2.0",
"configurations": [
{
"command": "./node_modules/.bin/astro dev",
"name": "Development server",
"request": "launch",
"type": "node-terminal"
}
]
}

View file

@ -1,54 +0,0 @@
# Astro Starter Kit: Deno
[![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/withastro/astro/tree/latest/examples/deno)
[![Open with CodeSandbox](https://assets.codesandbox.io/github/button-edit-lime.svg)](https://codesandbox.io/p/sandbox/github/withastro/astro/tree/latest/examples/deno)
[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/withastro/astro?devcontainer_path=.devcontainer/deno/devcontainer.json)
```sh
npm create astro@latest -- --template deno
```
> 🧑‍🚀 **Seasoned astronaut?** Delete this file. Have fun!
![basics](https://user-images.githubusercontent.com/4677417/186188965-73453154-fdec-4d6b-9c34-cb35c248ae5b.png)
## 🚀 Project Structure
Inside of your Astro project, you'll see the following folders and files:
```text
/
├── public/
│ └── favicon.svg
├── src/
│ ├── components/
│ │ └── Layout.astro
│ └── pages/
│ └── index.astro
├── package.json
└── tsconfig.json
```
Astro looks for `.astro` or `.md` files in the `src/pages/` directory. Each page is exposed as a route based on its file name.
There's nothing special about `src/components/`, but that's where we like to put any Astro/React/Vue/Svelte/Preact components.
Any static assets, like images, can be placed in the `public/` directory.
## 🧞 Commands
All commands are run from the root of the project, from a terminal:
| Command | Action |
| :------------------------ | :----------------------------------------------- |
| `npm install` | Installs dependencies |
| `npm run dev` | Starts local dev server at `localhost:4321` |
| `npm run build` | Build your production site to `./dist/` |
| `npm run preview` | Preview your build locally, before deploying |
| | (preview uses Deno CLI) |
| `npm run astro ...` | Run CLI commands like `astro add`, `astro check` |
| `npm run astro -- --help` | Get help using the Astro CLI |
## 👀 Want to learn more?
Feel free to check [our documentation](https://docs.astro.build) or jump into our [Discord server](https://astro.build/chat).

View file

@ -1,18 +0,0 @@
{
"name": "@example/deno",
"version": "0.0.1",
"private": true,
"scripts": {
"dev": "astro dev",
"start": "astro dev",
"build": "astro build",
"preview": "deno run --allow-net --allow-read --allow-env ./dist/server/entry.mjs",
"astro": "astro"
},
"dependencies": {
"astro": "^3.1.4"
},
"devDependencies": {
"@astrojs/deno": "^5.0.1"
}
}

View file

@ -1,9 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 128 128">
<path d="M50.4 78.5a75.1 75.1 0 0 0-28.5 6.9l24.2-65.7c.7-2 1.9-3.2 3.4-3.2h29c1.5 0 2.7 1.2 3.4 3.2l24.2 65.7s-11.6-7-28.5-7L67 45.5c-.4-1.7-1.6-2.8-2.9-2.8-1.3 0-2.5 1.1-2.9 2.7L50.4 78.5Zm-1.1 28.2Zm-4.2-20.2c-2 6.6-.6 15.8 4.2 20.2a17.5 17.5 0 0 1 .2-.7 5.5 5.5 0 0 1 5.7-4.5c2.8.1 4.3 1.5 4.7 4.7.2 1.1.2 2.3.2 3.5v.4c0 2.7.7 5.2 2.2 7.4a13 13 0 0 0 5.7 4.9v-.3l-.2-.3c-1.8-5.6-.5-9.5 4.4-12.8l1.5-1a73 73 0 0 0 3.2-2.2 16 16 0 0 0 6.8-11.4c.3-2 .1-4-.6-6l-.8.6-1.6 1a37 37 0 0 1-22.4 2.7c-5-.7-9.7-2-13.2-6.2Z" />
<style>
path { fill: #000; }
@media (prefers-color-scheme: dark) {
path { fill: #FFF; }
}
</style>
</svg>

Before

Width:  |  Height:  |  Size: 749 B

View file

@ -1,61 +0,0 @@
---
interface Props {
title: string;
}
const { title } = Astro.props as Props;
---
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<title>{title}</title>
</head>
<body>
<slot />
<style>
:root {
--font-size-base: clamp(1rem, 0.34vw + 0.91rem, 1.19rem);
--font-size-lg: clamp(1.2rem, 0.7vw + 1.2rem, 1.5rem);
--font-size-xl: clamp(2.44rem, 2.38vw + 1.85rem, 3rem);
--color-text: hsl(12, 5%, 4%);
--color-bg: hsl(10, 21%, 95%);
}
html {
font-family: system-ui, sans-serif;
font-size: var(--font-size-base);
color: var(--color-text);
background-color: var(--color-bg);
}
body {
margin: 0;
}
:global(h1) {
font-size: var(--font-size-xl);
}
:global(h2) {
font-size: var(--font-size-lg);
}
:global(code) {
font-family:
Menlo,
Monaco,
Lucida Console,
Liberation Mono,
DejaVu Sans Mono,
Bitstream Vera Sans Mono,
Courier New,
monospace;
}
</style>
</body>
</html>

View file

@ -1,188 +0,0 @@
---
import Layout from '../components/Layout.astro';
export const prerender = true;
---
<Layout title="Welcome to Astro (on Deno).">
<main>
<h1>Welcome to <span class="text-gradient">Astro</span> on Deno</h1>
<p class="instructions">
<strong>Your first mission:</strong> tweak this message to try our hot module reloading. Check
the <code>src/pages</code> directory!
</p>
<ul role="list" class="link-card-grid">
<li class="link-card">
<a href="https://astro.build/integrations/">
<h2>Integrations <span>&rarr;</span></h2>
<p>Add component frameworks, Tailwind, Partytown, and more!</p>
</a>
</li>
<li class="link-card">
<a href="https://astro.build/themes/">
<h2>Themes <span>&rarr;</span></h2>
<p>Explore a galaxy of community-built starters.</p>
</a>
</li>
<li class="link-card">
<a href="https://docs.astro.build/">
<h2>Docs <span>&rarr;</span></h2>
<p>Learn our complete feature set and explore the API.</p>
</a>
</li>
<li class="link-card">
<a href="https://astro.build/chat/">
<h2>Chat <span>&rarr;</span></h2>
<p>
Ask, contribute, and have fun on our community Discord
<svg
class="heart"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 512 512"
width="16"
height="16"
fill="currentColor"
>
<title>heart</title>
<path
d="M256 448l-30.164-27.211C118.718 322.442 48 258.61 48 179.095 48 114.221 97.918 64 162.4 64c36.399 0 70.717 16.742 93.6 43.947C278.882 80.742 313.199 64 349.6 64 414.082 64 464 114.221 464 179.095c0 79.516-70.719 143.348-177.836 241.694L256 448z"
></path>
</svg>
</p>
</a>
</li>
</ul>
</main>
</Layout>
<style>
:root {
--color-border: hsl(17, 24%, 90%);
--astro-gradient: linear-gradient(0deg, #4f39fa, #da62c4);
--link-gradient: linear-gradient(45deg, #4f39fa, #da62c4 30%, var(--color-border) 60%);
--night-sky-gradient: linear-gradient(
0deg,
#392362 -33%,
#431f69 10%,
#30216b 50%,
#1f1638 100%
);
}
h2 {
margin: 0;
transition: color 0.6s cubic-bezier(0.22, 1, 0.36, 1);
}
h2 span {
display: inline-block;
transition: transform 0.3s cubic-bezier(0.22, 1, 0.36, 1);
}
code {
font-size: 0.875em;
border: 0.1em solid var(--color-border);
border-radius: 4px;
padding: 0.15em 0.25em;
}
main {
margin: auto;
padding: 1em;
max-width: 60ch;
}
.text-gradient {
font-weight: 900;
background-image: var(--astro-gradient);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-size: 100% 200%;
background-position-y: 100%;
border-radius: 0.4rem;
animation: pulse 4s ease-in-out infinite;
}
@keyframes pulse {
0%,
100% {
background-position-y: 0%;
}
50% {
background-position-y: 80%;
}
}
.instructions {
line-height: 1.8;
margin-bottom: 2rem;
background-image: var(--night-sky-gradient);
padding: 1.5rem;
border-radius: 0.4rem;
color: var(--color-bg);
}
.link-card-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(24ch, 1fr));
gap: 1rem;
padding: 0;
}
.link-card {
list-style: none;
display: flex;
padding: 0.15rem;
background-image: var(--link-gradient);
background-size: 400%;
border-radius: 0.5rem;
background-position: 100%;
transition: background-position 0.6s cubic-bezier(0.22, 1, 0.36, 1);
}
.link-card > a {
width: 100%;
text-decoration: none;
line-height: 1.4;
padding: 1em 1.3em;
border-radius: 0.35rem;
color: var(--text-color);
background-color: white;
opacity: 0.8;
}
.link-card:is(:hover, :focus-within) {
background-position: 0;
}
.link-card:is(:hover, :focus-within) h2 {
color: #4f39fa;
}
.link-card:is(:hover, :focus-within) h2 span {
transform: translateX(2px);
}
.heart {
display: inline-block;
color: #da62c4;
animation: heartbeat 3s ease-in-out infinite;
}
@keyframes heartbeat {
0%,
50%,
100% {
transform: scale(1);
}
5% {
transform: scale(1.125);
}
10% {
transform: scale(1.05);
}
15% {
transform: scale(1.25);
}
}
</style>

View file

@ -1,3 +0,0 @@
{
"extends": "astro/tsconfigs/base"
}

View file

@ -11,9 +11,9 @@
"astro": "astro"
},
"dependencies": {
"@astrojs/alpinejs": "^0.3.0",
"@astrojs/alpinejs": "^0.3.1",
"@types/alpinejs": "^3.7.2",
"alpinejs": "^3.12.3",
"astro": "^3.1.4"
"astro": "^3.2.4"
}
}

View file

@ -11,9 +11,9 @@
"astro": "astro"
},
"dependencies": {
"@astrojs/lit": "^3.0.0",
"@astrojs/lit": "^3.0.1",
"@webcomponents/template-shadowroot": "^0.2.1",
"astro": "^3.1.4",
"astro": "^3.2.4",
"lit": "^2.8.0"
}
}

View file

@ -11,12 +11,12 @@
"astro": "astro"
},
"dependencies": {
"@astrojs/preact": "^3.0.0",
"@astrojs/react": "^3.0.2",
"@astrojs/solid-js": "^3.0.1",
"@astrojs/svelte": "^4.0.2",
"@astrojs/vue": "^3.0.0",
"astro": "^3.1.4",
"@astrojs/preact": "^3.0.1",
"@astrojs/react": "^3.0.3",
"@astrojs/solid-js": "^3.0.2",
"@astrojs/svelte": "^4.0.3",
"@astrojs/vue": "^3.0.1",
"astro": "^3.2.4",
"preact": "^10.17.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",

View file

@ -11,9 +11,9 @@
"astro": "astro"
},
"dependencies": {
"@astrojs/preact": "^3.0.0",
"@astrojs/preact": "^3.0.1",
"@preact/signals": "^1.2.1",
"astro": "^3.1.4",
"astro": "^3.2.4",
"preact": "^10.17.1"
}
}

View file

@ -11,10 +11,10 @@
"astro": "astro"
},
"dependencies": {
"@astrojs/react": "^3.0.2",
"@astrojs/react": "^3.0.3",
"@types/react": "^18.2.21",
"@types/react-dom": "^18.2.7",
"astro": "^3.1.4",
"astro": "^3.2.4",
"react": "^18.2.0",
"react-dom": "^18.2.0"
}

View file

@ -11,8 +11,8 @@
"astro": "astro"
},
"dependencies": {
"@astrojs/solid-js": "^3.0.1",
"astro": "^3.1.4",
"@astrojs/solid-js": "^3.0.2",
"astro": "^3.2.4",
"solid-js": "^1.7.11"
}
}

View file

@ -11,8 +11,8 @@
"astro": "astro"
},
"dependencies": {
"@astrojs/svelte": "^4.0.2",
"astro": "^3.1.4",
"@astrojs/svelte": "^4.0.3",
"astro": "^3.2.4",
"svelte": "^4.2.0"
}
}

View file

@ -11,8 +11,8 @@
"astro": "astro"
},
"dependencies": {
"@astrojs/vue": "^3.0.0",
"astro": "^3.1.4",
"@astrojs/vue": "^3.0.1",
"astro": "^3.2.4",
"vue": "^3.3.4"
}
}

View file

@ -11,7 +11,7 @@
"astro": "astro"
},
"dependencies": {
"@astrojs/node": "^6.0.1",
"astro": "^3.1.4"
"@astrojs/node": "^6.0.3",
"astro": "^3.2.4"
}
}

View file

@ -10,9 +10,9 @@ export default function createIntegration(): AstroIntegration {
// See the @astrojs/react integration for an example
// https://github.com/withastro/astro/blob/main/packages/integrations/react/src/index.ts
},
'astro:build:setup': ({ config, updateConfig }) => {
// See the @astrojs/netlify integration for an example
// https://github.com/withastro/astro/blob/main/packages/integrations/netlify/src/integration-functions.ts
'astro:build:setup': ({ pages, updateConfig }) => {
// See the @astrojs/lit integration for an example
// https://github.com/withastro/astro/blob/main/packages/integrations/lit/src/index.ts
},
'astro:build:done': ({ dir, routes }) => {
// See the @astrojs/partytown integration for an example

View file

@ -15,7 +15,7 @@
],
"scripts": {},
"devDependencies": {
"astro": "^3.1.4"
"astro": "^3.2.4"
},
"peerDependencies": {
"astro": "^2.0.0-beta.0"

View file

@ -12,8 +12,8 @@
"server": "node dist/server/entry.mjs"
},
"dependencies": {
"@astrojs/node": "^6.0.1",
"astro": "^3.1.4",
"@astrojs/node": "^6.0.3",
"astro": "^3.2.4",
"html-minifier": "^4.0.0"
}
}

View file

@ -11,6 +11,6 @@
"astro": "astro"
},
"dependencies": {
"astro": "^3.1.4"
"astro": "^3.2.4"
}
}

View file

@ -11,6 +11,6 @@
"astro": "astro"
},
"dependencies": {
"astro": "^3.1.4"
"astro": "^3.2.4"
}
}

View file

@ -11,6 +11,6 @@
"astro": "astro"
},
"dependencies": {
"astro": "^3.1.4"
"astro": "^3.2.4"
}
}

View file

@ -12,9 +12,9 @@
"server": "node dist/server/entry.mjs"
},
"dependencies": {
"@astrojs/node": "^6.0.1",
"@astrojs/svelte": "^4.0.2",
"astro": "^3.1.4",
"@astrojs/node": "^6.0.3",
"@astrojs/svelte": "^4.0.3",
"astro": "^3.2.4",
"svelte": "^4.2.0"
}
}

View file

@ -0,0 +1,30 @@
# Astro Movies View Transitions Demo
### 👉🏽 [Live Demo](https://astro-movies.pages.dev/)
![Screenshot](./screenshot.png)
## 🚀 Getting Started
1. Clone this repository and install dependencies with `npm install`.
2. Start the project locally with npm run dev, or deploy it to your favorite server.
3. Have fun! ✨
## 🧞 Commands
All commands are run from the root of the project, from a terminal:
| Command | Action |
| :--------------------- | :----------------------------------------------- |
| `npm install` | Installs dependencies |
| `npm run dev` | Starts local dev server at `localhost:3000` |
| `npm run build` | Build your production site to `./dist/` |
| `npm run preview` | Preview your build locally, before deploying |
| `npm run astro ...` | Run CLI commands like `astro add`, `astro check` |
| `npm run astro --help` | Get help using the Astro CLI |
## 👀 Want to learn more?
Check out [Astro's documentation](https://docs.astro.build) or jump into their [Discord server](https://astro.build/chat).
You can also reach out to [Maxi on Twitter](https://twitter.com/charca).

View file

@ -0,0 +1,15 @@
import { defineConfig } from 'astro/config';
import tailwind from '@astrojs/tailwind';
import nodejs from '@astrojs/node';
// https://astro.build/config
export default defineConfig({
integrations: [tailwind()],
output: 'server',
adapter: nodejs({ mode: 'standalone' }),
vite: {
define: {
'process.env.TMDB_API_KEY': JSON.stringify(process.env.TMDB_API_KEY),
},
},
});

View file

@ -0,0 +1,17 @@
{
"name": "@example/view-transitions",
"version": "0.0.1",
"private": true,
"scripts": {
"dev": "astro dev",
"start": "astro dev",
"build": "astro build",
"preview": "astro preview",
"astro": "astro"
},
"devDependencies": {
"@astrojs/tailwind": "^5.0.2",
"@astrojs/node": "^6.0.3",
"astro": "^3.2.4"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

View file

@ -0,0 +1,17 @@
<footer class="border border-t border-gray-800">
<div class="container mx-auto text-sm px-4 py-6">
Made with ❤️ by <a
href="https://www.twitter.com/charca"
target="_blank"
class="underline hover:text-gray-300">Maxi Ferreira</a
> — Powered by <a
href="https://astro.build"
target="_blank"
class="underline hover:text-gray-300">Astro</a
> and <a
href="https://www.themoviedb.org/documentation/api"
target="_blank"
class="underline hover:text-gray-300">TMDb API</a
>.
</div>
</footer>

View file

@ -0,0 +1,31 @@
---
const { movie } = Astro.props;
---
<div class="mt-8">
<a href={`/movies/${movie.id}`}>
<img
src={`https://image.tmdb.org/t/p/w500${movie.poster_path}`}
alt={`${movie.title} Poster`}
class="thumbnail hover:opacity-75 transition ease-in-out duration-150"
id={`movie-poster-${movie.id}`}
transition:name={`poster-${movie.id}`}
/>
</a>
<div class="mt-2">
<a href={`/movies/${movie.id}`} class="text-lg mt-2 hover:text-gray-300">{movie.title}</a>
<div class="flex items-center text-gray-400 text-sm mt-1">
<svg class="fill-current text-orange-500 w-4" viewBox="0 0 24 24"
><g data-name="Layer 2"
><path
d="M17.56 21a1 1 0 01-.46-.11L12 18.22l-5.1 2.67a1 1 0 01-1.45-1.06l1-5.63-4.12-4a1 1 0 01-.25-1 1 1 0 01.81-.68l5.7-.83 2.51-5.13a1 1 0 011.8 0l2.54 5.12 5.7.83a1 1 0 01.81.68 1 1 0 01-.25 1l-4.12 4 1 5.63a1 1 0 01-.4 1 1 1 0 01-.62.18z"
data-name="star"></path></g
></svg
>
<span class="ml-1">{movie.vote_average}</span>
<span class="mx-2">|</span>
<span>{movie.release_date}</span>
</div>
<div class="text-gray-400 text-sm">{movie.genres}</div>
</div>
</div>

View file

@ -0,0 +1,125 @@
---
const { data } = Astro.props;
const movie = {
...data,
poster_path: data.poster_path
? 'https://image.tmdb.org/t/p/w500/' + data.poster_path
: 'https://via.placeholder.com/500x750',
vote_average: (data.vote_average * 10).toFixed(2) + '%',
release_date: new Date(data.release_date).toLocaleDateString('en-us', {
year: 'numeric',
month: 'long',
day: 'numeric',
}),
genres: data.genres.map((g: any) => g.name).join(', '),
crew: data.credits.crew.slice(0, 3),
cast: data.credits.cast.slice(0, 5).map((c: any) => ({
...c,
profile_path: c.profile_path
? 'https://image.tmdb.org/t/p/w300/' + c.profile_path
: 'https://via.placeholder.com/300x450',
})),
images: data.images.backdrops.slice(0, 9),
};
---
<div class="movie-info border-b border-gray-800">
<div class="container mx-auto px-4 py-16 flex flex-col md:flex-row">
<div class="flex-none">
<img
src={movie.poster_path}
alt={`${movie.title} Poster`}
class="movie-poster w-64 lg:w-96"
id="movie-poster"
transition:name={`poster-${movie.id}`}
/>
</div>
<div class="md:ml-24">
<h2 class="text-4xl mt-4 md:mt-0 mb-2 font-semibold">{movie.title}</h2>
<div class="flex flex-wrap items-center text-gray-400 text-sm">
<svg class="fill-current text-orange-500 w-4" viewBox="0 0 24 24"
><g data-name="Layer 2"
><path
d="M17.56 21a1 1 0 01-.46-.11L12 18.22l-5.1 2.67a1 1 0 01-1.45-1.06l1-5.63-4.12-4a1 1 0 01-.25-1 1 1 0 01.81-.68l5.7-.83 2.51-5.13a1 1 0 011.8 0l2.54 5.12 5.7.83a1 1 0 01.81.68 1 1 0 01-.25 1l-4.12 4 1 5.63a1 1 0 01-.4 1 1 1 0 01-.62.18z"
data-name="star"></path></g
></svg
>
<span class="ml-1">{movie.vote_average}</span>
<span class="mx-2">|</span>
<span>{movie.release_date}</span>
<span class="mx-2">|</span>
<span>{movie.genres}</span>
</div>
<p class="text-gray-300 mt-8">
{movie.overview}
</p>
<div class="mt-12">
<h4 class="text-white font-semibold">Featured Crew</h4>
<div class="flex mt-4">
{
movie.crew.map((crew: any) => (
<div class="mr-8">
<div>{crew.name}</div>
<div class="text-gray-400 text-sm">{crew.job}</div>
</div>
))
}
</div>
</div>
</div>
</div>
</div>
<!-- end movie-info -->
<div class="movie-cast border-b border-gray-800">
<div class="container mx-auto px-4 py-16">
<h2 class="text-4xl font-semibold">Cast</h2>
<div class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-5 gap-8">
{
movie.cast.map((cast: any) => (
<div class="mt-8">
<span>
<img
id={`person-photo-${cast.id}`}
src={cast.profile_path}
alt={cast.name}
class="thumbnail hover:opacity-75 transition ease-in-out duration-150"
/>
</span>
<div class="mt-2">
<span class="text-lg mt-2 hover:text-gray:300">{cast.name}</span>
<div class="text-sm text-gray-400">{cast.character}</div>
</div>
</div>
))
}
</div>
</div>
</div>
<!-- end movie-cast -->
<div class="movie-images">
<div class="container mx-auto px-4 py-16">
<h2 class="text-4xl font-semibold">Images</h2>
<div class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-8">
{
movie.images.map((image: any) => (
<div class="mt-8">
<span>
<img
src={`https://image.tmdb.org/t/p/w500${image.file_path}`}
loading="lazy"
alt={movie.name}
class="hover:opacity-75 transition ease-in-out duration-150"
/>
</span>
</div>
))
}
</div>
</div>
</div>
<!-- end movie-images -->

View file

@ -0,0 +1,15 @@
---
import MovieCard from './MovieCard.astro';
import movies from '../popular-movies.json';
const popularMovies = movies.results;
---
<div class="container mx-auto px-4 pt-16 mb-16">
<div class="popular-movies">
<h2 class="uppercase tracking-wider text-orange-500 text-lg font-semibold">Popular Movies</h2>
<div class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-5 gap-8">
{popularMovies.map((movie) => <MovieCard movie={movie} />)}
</div>
</div>
<!-- end pouplar-movies -->
</div>

View file

@ -0,0 +1,18 @@
<nav class="nav border-b border-gray-800 sticky top-0 z-30 bg-gray-900">
<div
class="container mx-auto px-4 flex flex-col md:flex-row items-center justify-between px-4 py-6"
>
<ul class="flex flex-col md:flex-row items-center">
<li>
<a href="/" class="flex items-center font-bold text-xl">
<span>Movies</span>
&nbsp;
<span class="text-orange-500">List</span>
</a>
</li>
<li class="md:ml-16 mt-3 md:mt-0">
<a href="/" class="hover:text-gray-300">Movies</a>
</li>
</ul>
</div>
</nav>

View file

@ -0,0 +1,12 @@
import { z, defineCollection } from 'astro:content';
const movies = defineCollection({
type: 'data',
schema: z.object({
data: z.any(),
}),
});
// Expose your defined collection to Astro
// with the `collections` export
export const collections = { movies };

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,345 @@
{
"data": {
"adult": false,
"backdrop_path": "/e8FyMnifoN5BMuRFE97fS1lJZ6S.jpg",
"belongs_to_collection": {
"id": 1153632,
"name": "Darkland Collection",
"poster_path": null,
"backdrop_path": null
},
"budget": 0,
"genres": [
{ "id": 28, "name": "Action" },
{ "id": 53, "name": "Thriller" }
],
"homepage": "",
"id": 1085218,
"imdb_id": "tt20204996",
"original_language": "da",
"original_title": "Underverden 2",
"overview": "Seven years ago, Zaid went to war against the Copenhagen underworld to avenge his dead brother. His identity as a respected doctor of cardiology and life as a family man is but a fading dream, and in prison Zaid suffers the loss of his son Noah, whom he barely knows. When a police agent approaches Zaid and offers him a deal to be released in exchange for infiltrating the Copenhagen underworld, he sees his chance to reclaim the remnants of the family life he left behind. But everything has a price, and Zaid realizes that he has now seriously endangered his son's life. After all, once you become part of the underworld, is there any way out?",
"popularity": 524.476,
"poster_path": "/c8B4DsVcFVDLVmbpHMHU3RjLNAV.jpg",
"production_companies": [
{
"id": 64293,
"logo_path": "/lbYGnir9KeY8NyQZrUFZbf3QDej.png",
"name": "Profile Pictures",
"origin_country": "DK"
}
],
"production_countries": [{ "iso_3166_1": "DK", "name": "Denmark" }],
"release_date": "2023-04-13",
"revenue": 0,
"runtime": 110,
"spoken_languages": [
{ "english_name": "Arabic", "iso_639_1": "ar", "name": "العربية" },
{ "english_name": "Danish", "iso_639_1": "da", "name": "Dansk" }
],
"status": "Released",
"tagline": "",
"title": "Darkland: The Return",
"video": false,
"vote_average": 6.32,
"vote_count": 64,
"credits": {
"cast": [
{
"adult": false,
"gender": 2,
"id": 234907,
"known_for_department": "Acting",
"name": "Dar Salim",
"original_name": "Dar Salim",
"popularity": 16.442,
"profile_path": "/oTYCqdF6nfZTsvt1fbypi54ydI.jpg",
"cast_id": 1,
"character": "Zaid",
"credit_id": "6429b39701b1ca0113cc2840",
"order": 0
},
{
"adult": false,
"gender": 1,
"id": 90514,
"known_for_department": "Acting",
"name": "Birgitte Hjort Sørensen",
"original_name": "Birgitte Hjort Sørensen",
"popularity": 9.741,
"profile_path": "/uPak0FlCPdsc9B1pw4bBkuaMLXT.jpg",
"cast_id": 2,
"character": "Helle",
"credit_id": "6429b3d101b1ca00d5e8507e",
"order": 1
},
{
"adult": false,
"gender": 1,
"id": 32682,
"known_for_department": "Acting",
"name": "Stine Fischer Christensen",
"original_name": "Stine Fischer Christensen",
"popularity": 3.87,
"profile_path": "/6MYODCa28L1IzfhcYTUZUYThoF2.jpg",
"cast_id": 3,
"character": "Stine",
"credit_id": "6429b42c9cc67b05796bcdcc",
"order": 2
},
{
"adult": false,
"gender": 0,
"id": 1178394,
"known_for_department": "Acting",
"name": "Henrik Vestergaard",
"original_name": "Henrik Vestergaard",
"popularity": 0.766,
"profile_path": "/1Opgkbdkyt1x5iEOLgV3VJ29ZpA.jpg",
"cast_id": 4,
"character": "Lars",
"credit_id": "6429b45401b1ca0097fdfb0f",
"order": 3
},
{
"adult": false,
"gender": 0,
"id": 3236472,
"known_for_department": "Acting",
"name": "Soheil Bavi",
"original_name": "Soheil Bavi",
"popularity": 0.6,
"profile_path": null,
"cast_id": 5,
"character": "Muhdir",
"credit_id": "6429b4828de0ae00b65514de",
"order": 4
},
{
"adult": false,
"gender": 0,
"id": 3991209,
"known_for_department": "Acting",
"name": "Jack Pedersen",
"original_name": "Jack Pedersen",
"popularity": 0.648,
"profile_path": null,
"cast_id": 6,
"character": "Shahin",
"credit_id": "6429b4f4ac8e6b00d32aa4eb",
"order": 5
},
{
"adult": false,
"gender": 0,
"id": 2595279,
"known_for_department": "Acting",
"name": "Mohamed Djeziri",
"original_name": "Mohamed Djeziri",
"popularity": 0.84,
"profile_path": null,
"cast_id": 11,
"character": "",
"credit_id": "64c14243871b340101072cf6",
"order": 6
},
{
"adult": false,
"gender": 0,
"id": 4188787,
"known_for_department": "Acting",
"name": "Abud Mustafa",
"original_name": "Abud Mustafa",
"popularity": 0.98,
"profile_path": null,
"cast_id": 12,
"character": "",
"credit_id": "64c6c269db8a0000e3286594",
"order": 7
},
{
"adult": false,
"gender": 0,
"id": 4188788,
"known_for_department": "Acting",
"name": "Ahmad Ayman",
"original_name": "Ahmad Ayman",
"popularity": 0.6,
"profile_path": null,
"cast_id": 13,
"character": "",
"credit_id": "64c6c27f63aad20209a58505",
"order": 8
},
{
"adult": false,
"gender": 0,
"id": 4188789,
"known_for_department": "Acting",
"name": "Sebastian Nørgaard",
"original_name": "Sebastian Nørgaard",
"popularity": 0.6,
"profile_path": null,
"cast_id": 14,
"character": "",
"credit_id": "64c6c298db8a0000e32865ab",
"order": 9
},
{
"adult": false,
"gender": 0,
"id": 4188791,
"known_for_department": "Acting",
"name": "Hamed \"Baloosh\" Balosha",
"original_name": "Hamed \"Baloosh\" Balosha",
"popularity": 0.6,
"profile_path": null,
"cast_id": 15,
"character": "",
"credit_id": "64c6c2a3eec5b500ff5262cb",
"order": 10
},
{
"adult": false,
"gender": 0,
"id": 3549264,
"known_for_department": "Acting",
"name": "Noah Carter",
"original_name": "Noah Carter",
"popularity": 0.6,
"profile_path": null,
"cast_id": 16,
"character": "",
"credit_id": "64c6c2b0cadb6b00c82a2404",
"order": 11
},
{
"adult": false,
"gender": 0,
"id": 4188792,
"known_for_department": "Acting",
"name": "Asgar Hansen",
"original_name": "Asgar Hansen",
"popularity": 0.6,
"profile_path": null,
"cast_id": 17,
"character": "",
"credit_id": "64c6c2bc30f79c00c781a97c",
"order": 12
}
],
"crew": [
{
"adult": false,
"gender": 0,
"id": 1183636,
"known_for_department": "Directing",
"name": "Fenar Ahmad",
"original_name": "Fenar Ahmad",
"popularity": 1.646,
"profile_path": null,
"credit_id": "6429b673c04429026b13a94a",
"department": "Directing",
"job": "Director"
},
{
"adult": false,
"gender": 0,
"id": 1183636,
"known_for_department": "Directing",
"name": "Fenar Ahmad",
"original_name": "Fenar Ahmad",
"popularity": 1.646,
"profile_path": null,
"credit_id": "642ed070158c8501263ad755",
"department": "Writing",
"job": "Writer"
},
{
"adult": false,
"gender": 0,
"id": 2405913,
"known_for_department": "Directing",
"name": "Behrouz Bigdeli",
"original_name": "Behrouz Bigdeli",
"popularity": 0.6,
"profile_path": null,
"credit_id": "642ed08058361b00f2f13338",
"department": "Writing",
"job": "Writer"
}
]
},
"videos": { "results": [] },
"images": {
"backdrops": [
{
"aspect_ratio": 1.778,
"height": 1080,
"iso_639_1": "da",
"file_path": "/4wVFtesa5YEWuAUHRcxoCN1Y1uN.jpg",
"vote_average": 5.172,
"vote_count": 1,
"width": 1920
},
{
"aspect_ratio": 1.778,
"height": 720,
"iso_639_1": null,
"file_path": "/e8FyMnifoN5BMuRFE97fS1lJZ6S.jpg",
"vote_average": 0,
"vote_count": 0,
"width": 1280
},
{
"aspect_ratio": 1.778,
"height": 1116,
"iso_639_1": null,
"file_path": "/tDT465D3JZiABgz2uug9jCgOUlw.jpg",
"vote_average": 0,
"vote_count": 0,
"width": 1984
}
],
"logos": [],
"posters": [
{
"aspect_ratio": 0.667,
"height": 3000,
"iso_639_1": "da",
"file_path": "/A8EPXv3SV9qiNCIttIM4ezJRmhW.jpg",
"vote_average": 5.312,
"vote_count": 1,
"width": 2000
},
{
"aspect_ratio": 0.667,
"height": 1200,
"iso_639_1": "da",
"file_path": "/A0cxUcMWBruPknr5ZSePIYFfe7z.jpg",
"vote_average": 5.172,
"vote_count": 1,
"width": 800
},
{
"aspect_ratio": 0.7,
"height": 2834,
"iso_639_1": "en",
"file_path": "/c8B4DsVcFVDLVmbpHMHU3RjLNAV.jpg",
"vote_average": 0,
"vote_count": 0,
"width": 1984
},
{
"aspect_ratio": 0.7,
"height": 2834,
"iso_639_1": "en",
"file_path": "/my1ve6HKygOVNYJBi3A0pRpPm2l.jpg",
"vote_average": 0,
"vote_count": 0,
"width": 1984
}
]
}
}
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,856 @@
{
"data": {
"adult": false,
"backdrop_path": "/jkKVLzLWjSvTnc84VzeljhSy6j8.jpg",
"belongs_to_collection": {
"id": 702624,
"name": "After Collection",
"poster_path": "/250ewaLutOJXqBBqMKxCHD1KpCL.jpg",
"backdrop_path": "/zZTy8G3sEVZNv0yGssgc7DvPUQJ.jpg"
},
"budget": 14000000,
"genres": [
{ "id": 10749, "name": "Romance" },
{ "id": 18, "name": "Drama" }
],
"homepage": "",
"id": 820525,
"imdb_id": "tt15334488",
"original_language": "en",
"original_title": "After Everything",
"overview": "Besieged by writers block and the crushing breakup with Tessa, Hardin travels to Portugal in search of a woman he wronged in the past and to find himself. Hoping to win back Tessa, he realizes he needs to change his ways before he can make the ultimate commitment.",
"popularity": 650.272,
"poster_path": "/gZLGCibvFY4zmt8sWUZcbBTHRtk.jpg",
"production_companies": [
{
"id": 6626,
"logo_path": "/A1BnMoWjzjOrjzpWimyBQkf84mS.png",
"name": "Voltage Pictures",
"origin_country": "US"
},
{
"id": 107108,
"logo_path": "/5mxc7uNtFOZm2ly0BxixxGPvPlb.png",
"name": "Wattpad",
"origin_country": "US"
}
],
"production_countries": [{ "iso_3166_1": "US", "name": "United States of America" }],
"release_date": "2023-09-13",
"revenue": 962741,
"runtime": 93,
"spoken_languages": [
{ "english_name": "English", "iso_639_1": "en", "name": "English" },
{ "english_name": "Portuguese", "iso_639_1": "pt", "name": "Português" }
],
"status": "Released",
"tagline": "",
"title": "After Everything",
"video": false,
"vote_average": 6.407,
"vote_count": 27,
"credits": {
"cast": [
{
"adult": false,
"gender": 2,
"id": 1114487,
"known_for_department": "Acting",
"name": "Hero Fiennes Tiffin",
"original_name": "Hero Fiennes Tiffin",
"popularity": 15.891,
"profile_path": "/6zMrrZvOMH6uGwEFoK0Uo8sZvxL.jpg",
"cast_id": 5,
"character": "Hardin Scott",
"credit_id": "60d374f40e64af0046370008",
"order": 0
},
{
"adult": false,
"gender": 1,
"id": 1694711,
"known_for_department": "Acting",
"name": "Mimi Keene",
"original_name": "Mimi Keene",
"popularity": 7.403,
"profile_path": "/7bUgfaycm0f6PgEn3eLo8oANByO.jpg",
"cast_id": 24,
"character": "Nathalie",
"credit_id": "6441b4e7651fcf02fb9c2851",
"order": 1
},
{
"adult": false,
"gender": 2,
"id": 2849483,
"known_for_department": "Acting",
"name": "Benjamin Mascolo",
"original_name": "Benjamin Mascolo",
"popularity": 4.235,
"profile_path": "/zkKiB05KRFCIQdMVnseQlatMLRq.jpg",
"cast_id": 23,
"character": "Sebastian",
"credit_id": "6441b4cab3f6f5055a9d8f4a",
"order": 2
},
{
"adult": false,
"gender": 1,
"id": 20805,
"known_for_department": "Acting",
"name": "Louise Lombard",
"original_name": "Louise Lombard",
"popularity": 17.846,
"profile_path": "/6znYbOI2Z8PfzZ6p9jHG5QdAeb2.jpg",
"cast_id": 22,
"character": "Trish Daniels",
"credit_id": "63a8788e0f21c6007871434e",
"order": 3
},
{
"adult": false,
"gender": 2,
"id": 32203,
"known_for_department": "Acting",
"name": "Stephen Moyer",
"original_name": "Stephen Moyer",
"popularity": 12.55,
"profile_path": "/xprwOCXa2cNkjhrGtcJp0VfJMlZ.jpg",
"cast_id": 7,
"character": "Christian Vance",
"credit_id": "63a638291f748b008a0a1614",
"order": 4
},
{
"adult": false,
"gender": 1,
"id": 20373,
"known_for_department": "Acting",
"name": "Arielle Kebbel",
"original_name": "Arielle Kebbel",
"popularity": 23.827,
"profile_path": "/dmYiAeWoeVsRdT4UBBGuW9gBfjQ.jpg",
"cast_id": 6,
"character": "Kim Vance",
"credit_id": "63a638191f748b007cc00f2f",
"order": 5
},
{
"adult": false,
"gender": 1,
"id": 3009693,
"known_for_department": "Acting",
"name": "Jessica Webber",
"original_name": "Jessica Webber",
"popularity": 1.15,
"profile_path": null,
"cast_id": 20,
"character": "Maddy",
"credit_id": "63a64fa98a84d200b4ce9858",
"order": 6
},
{
"adult": false,
"gender": 1,
"id": 3069742,
"known_for_department": "Acting",
"name": "Cora Kirk",
"original_name": "Cora Kirk",
"popularity": 1.404,
"profile_path": "/4av80vVFZSBuKJyzXqEXLE8Vftc.jpg",
"cast_id": 21,
"character": "Freya",
"credit_id": "63a64fb1eb093200a0c1594c",
"order": 7
},
{
"adult": false,
"gender": 1,
"id": 2173697,
"known_for_department": "Acting",
"name": "Rosa Escoda",
"original_name": "Rosa Escoda",
"popularity": 4.382,
"profile_path": "/bnGlICypCtpuiKe5mHCnijESI3W.jpg",
"cast_id": 27,
"character": "Kat",
"credit_id": "6503cbc1efea7a00e036e0f1",
"order": 8
},
{
"adult": false,
"gender": 1,
"id": 2677100,
"known_for_department": "Acting",
"name": "Ella Martine",
"original_name": "Ella Martine",
"popularity": 0.6,
"profile_path": "/d9uZ2tqibHTno0ZKPUc9FZNXhTn.jpg",
"cast_id": 28,
"character": "Naomi",
"credit_id": "6503cbd7e0ca7f010deb819c",
"order": 9
},
{
"adult": false,
"gender": 1,
"id": 2026999,
"known_for_department": "Acting",
"name": "Laura Dutra",
"original_name": "Laura Dutra",
"popularity": 1.8,
"profile_path": "/ipSilYFln0N3UdiL3eboTv8XWS1.jpg",
"cast_id": 29,
"character": "Paloma",
"credit_id": "6503cbedefea7a00aad915a0",
"order": 10
},
{
"adult": false,
"gender": 2,
"id": 2035329,
"known_for_department": "Acting",
"name": "Chance Perdomo",
"original_name": "Chance Perdomo",
"popularity": 9.723,
"profile_path": "/xRRDtdHhTewrKMj5cpcmEkPNmuP.jpg",
"cast_id": 30,
"character": "Landon Scott",
"credit_id": "6503cbfed7dcd20139cc9553",
"order": 11
},
{
"adult": false,
"gender": 1,
"id": 142115,
"known_for_department": "Acting",
"name": "Kiana Madeira",
"original_name": "Kiana Madeira",
"popularity": 19.805,
"profile_path": "/HgCI95xnSZJaE18d15n7PykOU7.jpg",
"cast_id": 31,
"character": "Nora",
"credit_id": "6503cc206a2227011a7c6353",
"order": 12
},
{
"adult": false,
"gender": 2,
"id": 20960,
"known_for_department": "Acting",
"name": "Rob Estes",
"original_name": "Rob Estes",
"popularity": 9.434,
"profile_path": "/b24y5Tv4A8DUjkfYpJ1l1qpkhyv.jpg",
"cast_id": 32,
"character": "Ken Scott",
"credit_id": "6503cc31efea7a0137d3de3b",
"order": 13
},
{
"adult": false,
"gender": 1,
"id": 20373,
"known_for_department": "Acting",
"name": "Arielle Kebbel",
"original_name": "Arielle Kebbel",
"popularity": 23.827,
"profile_path": "/dmYiAeWoeVsRdT4UBBGuW9gBfjQ.jpg",
"cast_id": 33,
"character": "Kimberley",
"credit_id": "6503cc596a222700abaa07d9",
"order": 14
},
{
"adult": false,
"gender": 2,
"id": 86653,
"known_for_department": "Acting",
"name": "Carter Jenkins",
"original_name": "Carter Jenkins",
"popularity": 5.084,
"profile_path": "/fGVndWC3hgwK1uVrhiyzTUyIaxW.jpg",
"cast_id": 34,
"character": "Robert Freeman",
"credit_id": "6503cc65ffc9de0edf625db1",
"order": 15
},
{
"adult": false,
"gender": 0,
"id": 1910292,
"known_for_department": "Acting",
"name": "Ana Ivanova",
"original_name": "Ana Ivanova",
"popularity": 1.307,
"profile_path": "/kT9AL9N1zwi4gksDPdLXGAThbpx.jpg",
"cast_id": 35,
"character": "Emery",
"credit_id": "6503cc95efea7a00c3986356",
"order": 16
},
{
"adult": false,
"gender": 2,
"id": 2916706,
"known_for_department": "Acting",
"name": "Anton Kottas",
"original_name": "Anton Kottas",
"popularity": 3.44,
"profile_path": "/trj5wj5Y6Tvj649tbn1a4IG6YfG.jpg",
"cast_id": 36,
"character": "Smith",
"credit_id": "6503cca5ffc9de0ee20aaf80",
"order": 17
},
{
"adult": false,
"gender": 1,
"id": 1753914,
"known_for_department": "Acting",
"name": "Josephine Langford",
"original_name": "Josephine Langford",
"popularity": 27.865,
"profile_path": "/8Fj1UIFRJA0B5Zo22KwML5d3Mr3.jpg",
"cast_id": 39,
"character": "Tessa Young",
"credit_id": "650a7334cadb6b00e11f6961",
"order": 18
}
],
"crew": [
{
"adult": false,
"gender": 2,
"id": 20739,
"known_for_department": "Directing",
"name": "Adam Shankman",
"original_name": "Adam Shankman",
"popularity": 8.011,
"profile_path": "/zZmZgVp5OTU2eSMCDuOXGlQ4fBR.jpg",
"credit_id": "65072f3b42d8a5011bd6f839",
"department": "Directing",
"job": "Director"
},
{
"adult": false,
"gender": 1,
"id": 20742,
"known_for_department": "Production",
"name": "Jennifer Gibgot",
"original_name": "Jennifer Gibgot",
"popularity": 1.159,
"profile_path": null,
"credit_id": "63a64f171108a800bab73fcd",
"department": "Production",
"job": "Producer"
},
{
"adult": false,
"gender": 2,
"id": 46088,
"known_for_department": "Production",
"name": "Mark Canton",
"original_name": "Mark Canton",
"popularity": 2.299,
"profile_path": "/7OiY4eak3DztX0lSj4cbmKLQuaj.jpg",
"credit_id": "63a64f03907f2600aa7262a1",
"department": "Production",
"job": "Producer"
},
{
"adult": false,
"gender": 2,
"id": 61921,
"known_for_department": "Production",
"name": "Courtney Solomon",
"original_name": "Courtney Solomon",
"popularity": 2.006,
"profile_path": "/xujLAPgpM1JXLqE0X4mWVrPTmqd.jpg",
"credit_id": "63a64f35907f2600da9a63bf",
"department": "Production",
"job": "Producer"
},
{
"adult": false,
"gender": 2,
"id": 1031200,
"known_for_department": "Production",
"name": "Nicolas Chartier",
"original_name": "Nicolas Chartier",
"popularity": 1.901,
"profile_path": "/59ptYCph60CtAtLmWuC9dASHhsp.jpg",
"credit_id": "63a64f0d1f748b007cc01cfd",
"department": "Production",
"job": "Producer"
},
{
"adult": false,
"gender": 0,
"id": 1179667,
"known_for_department": "Lighting",
"name": "Diego Moyano",
"original_name": "Diego Moyano",
"popularity": 0.6,
"profile_path": null,
"credit_id": "63a64f908a84d200d9c3b03a",
"department": "Lighting",
"job": "Gaffer"
},
{
"adult": false,
"gender": 1,
"id": 1193192,
"known_for_department": "Production",
"name": "Carolyn McLeod",
"original_name": "Carolyn McLeod",
"popularity": 0.612,
"profile_path": null,
"credit_id": "63a64f7404b596007d427d31",
"department": "Production",
"job": "Casting"
},
{
"adult": false,
"gender": 1,
"id": 1448492,
"known_for_department": "Directing",
"name": "Castille Landon",
"original_name": "Castille Landon",
"popularity": 5.18,
"profile_path": "/s1oXtmqyG9X0uDfiU5HidPB6BJx.jpg",
"credit_id": "645009ff52dc7f02dddb5ed5",
"department": "Writing",
"job": "Screenplay"
},
{
"adult": false,
"gender": 0,
"id": 1540619,
"known_for_department": "Camera",
"name": "Joshua Reis",
"original_name": "Joshua Reis",
"popularity": 0.984,
"profile_path": null,
"credit_id": "63a64f681108a800c60a4d19",
"department": "Camera",
"job": "Director of Photography"
},
{
"adult": false,
"gender": 2,
"id": 1551998,
"known_for_department": "Production",
"name": "Brian Pitt",
"original_name": "Brian Pitt",
"popularity": 2.997,
"profile_path": null,
"credit_id": "63a64f2a04b59600918423ea",
"department": "Production",
"job": "Producer"
},
{
"adult": false,
"gender": 0,
"id": 1552003,
"known_for_department": "Production",
"name": "David Shojai",
"original_name": "David Shojai",
"popularity": 0.6,
"profile_path": null,
"credit_id": "63a64f592b8a43007dddfc26",
"department": "Production",
"job": "Co-Producer"
},
{
"adult": false,
"gender": 1,
"id": 1664826,
"known_for_department": "Writing",
"name": "Anna Todd",
"original_name": "Anna Todd",
"popularity": 2.633,
"profile_path": "/b0L0Hicos8ZeEXt96Jf9wDed8FS.jpg",
"credit_id": "6450089f2fccee02e4cebc26",
"department": "Writing",
"job": "Novel"
},
{
"adult": false,
"gender": 0,
"id": 3032242,
"known_for_department": "Art",
"name": "Alexandra Tibbe",
"original_name": "Alexandra Tibbe",
"popularity": 0.6,
"profile_path": null,
"credit_id": "63a64f812b8a4300b60617fd",
"department": "Art",
"job": "Set Decoration"
},
{
"adult": false,
"gender": 2,
"id": 3055946,
"known_for_department": "Production",
"name": "Aron Levitz",
"original_name": "Aron Levitz",
"popularity": 0.6,
"profile_path": null,
"credit_id": "63a64f211f748b00826608cc",
"department": "Production",
"job": "Producer"
},
{
"adult": false,
"gender": 0,
"id": 3216486,
"known_for_department": "Acting",
"name": "Taylor Conrod",
"original_name": "Taylor Conrod",
"popularity": 0.6,
"profile_path": null,
"credit_id": "63a64f4c04b596007d427cfc",
"department": "Production",
"job": "Co-Producer"
}
]
},
"videos": {
"results": [
{
"iso_639_1": "en",
"iso_3166_1": "US",
"name": "Official Trailer",
"key": "NsmopvKNSE4",
"site": "YouTube",
"size": 1080,
"type": "Trailer",
"official": true,
"published_at": "2023-05-01T12:00:05.000Z",
"id": "64bd958d0ed2ab00c5e3af6a"
},
{
"iso_639_1": "en",
"iso_3166_1": "US",
"name": "Hessa (Official Clip)",
"key": "iVg7CDtG3MQ",
"site": "YouTube",
"size": 1080,
"type": "Clip",
"official": true,
"published_at": "2023-02-14T13:00:28.000Z",
"id": "63ebc244813cb60096aa356a"
},
{
"iso_639_1": "en",
"iso_3166_1": "US",
"name": "Official Teaser",
"key": "zmgbPv7lGrk",
"site": "YouTube",
"size": 1080,
"type": "Teaser",
"official": true,
"published_at": "2022-12-23T17:34:00.000Z",
"id": "63c169ee23be4600d960ae6d"
}
]
},
"images": {
"backdrops": [
{
"aspect_ratio": 1.778,
"height": 720,
"iso_639_1": null,
"file_path": "/jkKVLzLWjSvTnc84VzeljhSy6j8.jpg",
"vote_average": 5.384,
"vote_count": 2,
"width": 1280
},
{
"aspect_ratio": 1.778,
"height": 2160,
"iso_639_1": null,
"file_path": "/x6y6AHY3UoCeOP6kwZain7WNLPN.jpg",
"vote_average": 5.312,
"vote_count": 1,
"width": 3840
},
{
"aspect_ratio": 1.778,
"height": 2160,
"iso_639_1": null,
"file_path": "/ol32sTlLzayf7y3KbJrfuQkLmT8.jpg",
"vote_average": 5.312,
"vote_count": 1,
"width": 3840
},
{
"aspect_ratio": 1.778,
"height": 2160,
"iso_639_1": null,
"file_path": "/jL9pvfEep0houuNFMSEjinBm6Jh.jpg",
"vote_average": 0,
"vote_count": 0,
"width": 3840
},
{
"aspect_ratio": 1.778,
"height": 2160,
"iso_639_1": null,
"file_path": "/xZuhDaKDpWDG0sE3Dx6CIR8DeaN.jpg",
"vote_average": 0,
"vote_count": 0,
"width": 3840
},
{
"aspect_ratio": 1.778,
"height": 2160,
"iso_639_1": null,
"file_path": "/zg5rp4R3RkGApxWM03jUWJQzXGg.jpg",
"vote_average": 0,
"vote_count": 0,
"width": 3840
}
],
"logos": [
{
"aspect_ratio": 1.81,
"height": 749,
"iso_639_1": "en",
"file_path": "/r7eYlJVm3OSVBA78Wg3kSUmCKQ7.png",
"vote_average": 0,
"vote_count": 0,
"width": 1356
},
{
"aspect_ratio": 1.81,
"height": 749,
"iso_639_1": "en",
"file_path": "/t3wmFD8ghWeP1EEjahgD0MtcPM9.png",
"vote_average": 0,
"vote_count": 0,
"width": 1356
}
],
"posters": [
{
"aspect_ratio": 0.667,
"height": 3000,
"iso_639_1": "en",
"file_path": "/gZLGCibvFY4zmt8sWUZcbBTHRtk.jpg",
"vote_average": 5.318,
"vote_count": 3,
"width": 2000
},
{
"aspect_ratio": 0.667,
"height": 3000,
"iso_639_1": "ru",
"file_path": "/qMPcBNHcgclpl4IUiriSVcyt2Xr.jpg",
"vote_average": 5.312,
"vote_count": 1,
"width": 2000
},
{
"aspect_ratio": 0.667,
"height": 3000,
"iso_639_1": "es",
"file_path": "/jO3VGQi5sHIj2BGS963g1F74yCq.jpg",
"vote_average": 5.312,
"vote_count": 1,
"width": 2000
},
{
"aspect_ratio": 0.667,
"height": 1020,
"iso_639_1": "sk",
"file_path": "/7q9Q3OFu4E2UwTUnwGTZx79fqgj.jpg",
"vote_average": 5.312,
"vote_count": 1,
"width": 680
},
{
"aspect_ratio": 0.671,
"height": 1176,
"iso_639_1": "ar",
"file_path": "/d0qw9hiNwhRmfw4yAc44pep6vhz.jpg",
"vote_average": 5.252,
"vote_count": 4,
"width": 789
},
{
"aspect_ratio": 0.667,
"height": 2466,
"iso_639_1": "en",
"file_path": "/aJbrGWjOMwguiCSAGBcpoWGgpXf.jpg",
"vote_average": 5.246,
"vote_count": 2,
"width": 1644
},
{
"aspect_ratio": 0.667,
"height": 2466,
"iso_639_1": "en",
"file_path": "/uQxjZGU6rxSPSMeAJPJQlmfV3ys.jpg",
"vote_average": 5.246,
"vote_count": 2,
"width": 1644
},
{
"aspect_ratio": 0.667,
"height": 1500,
"iso_639_1": "en",
"file_path": "/8oibiRBkwSHFDamazdrEB5fWvXN.jpg",
"vote_average": 5.18,
"vote_count": 3,
"width": 1000
},
{
"aspect_ratio": 0.667,
"height": 3000,
"iso_639_1": "en",
"file_path": "/3PqW0elNnj5tk4XD9o82djTknGd.jpg",
"vote_average": 5.18,
"vote_count": 3,
"width": 2000
},
{
"aspect_ratio": 0.667,
"height": 3000,
"iso_639_1": "es",
"file_path": "/zXDnVeyWwvhLYbaQjnei0A6vohx.jpg",
"vote_average": 5.172,
"vote_count": 1,
"width": 2000
},
{
"aspect_ratio": 0.667,
"height": 3000,
"iso_639_1": "en",
"file_path": "/6bPnDIGG8RBncFPIUNxM6GAW0Ox.jpg",
"vote_average": 5.172,
"vote_count": 1,
"width": 2000
},
{
"aspect_ratio": 0.667,
"height": 3000,
"iso_639_1": "uk",
"file_path": "/v9qWcfkC3nJOASotuFdJ5huqg6l.jpg",
"vote_average": 5.172,
"vote_count": 1,
"width": 2000
},
{
"aspect_ratio": 0.667,
"height": 1714,
"iso_639_1": "es",
"file_path": "/nm7rgAYCdATbHgm6CjtoSNvON9k.jpg",
"vote_average": 5.172,
"vote_count": 1,
"width": 1143
},
{
"aspect_ratio": 0.666,
"height": 2000,
"iso_639_1": "fr",
"file_path": "/brIDXQSf02a09i13xvMDTkRlO7z.jpg",
"vote_average": 0,
"vote_count": 0,
"width": 1333
},
{
"aspect_ratio": 0.665,
"height": 1351,
"iso_639_1": "pt",
"file_path": "/tRjzdNiFHda6lrXySOQPyY3OtCA.jpg",
"vote_average": 0,
"vote_count": 0,
"width": 899
},
{
"aspect_ratio": 0.667,
"height": 3000,
"iso_639_1": "en",
"file_path": "/mhjf22NsRXY4HKRbaUlfZAt7Swb.jpg",
"vote_average": 0,
"vote_count": 0,
"width": 2000
},
{
"aspect_ratio": 0.667,
"height": 3000,
"iso_639_1": "en",
"file_path": "/gh7JdLfrjewoA00xeMr0ju0PMwd.jpg",
"vote_average": 0,
"vote_count": 0,
"width": 2000
},
{
"aspect_ratio": 0.667,
"height": 3000,
"iso_639_1": null,
"file_path": "/moIOvJIdvvwriBiaKTehcmIeOf9.jpg",
"vote_average": 0,
"vote_count": 0,
"width": 2000
},
{
"aspect_ratio": 0.667,
"height": 3000,
"iso_639_1": "he",
"file_path": "/ao0uyI21djx9uLv6voAjoaetX9O.jpg",
"vote_average": 0,
"vote_count": 0,
"width": 2000
},
{
"aspect_ratio": 0.667,
"height": 3000,
"iso_639_1": "nl",
"file_path": "/z7Yq7vkVts9yeHCTFqIOEJkhJbi.jpg",
"vote_average": 0,
"vote_count": 0,
"width": 2000
},
{
"aspect_ratio": 0.667,
"height": 1350,
"iso_639_1": "hr",
"file_path": "/fZog1nBWjNPQtPtoR1AFrmdbuG5.jpg",
"vote_average": 0,
"vote_count": 0,
"width": 900
},
{
"aspect_ratio": 0.667,
"height": 3000,
"iso_639_1": "bg",
"file_path": "/naMHX4mvqEAM4UbMox0MYYoFaPd.jpg",
"vote_average": 0,
"vote_count": 0,
"width": 2000
},
{
"aspect_ratio": 0.667,
"height": 3000,
"iso_639_1": "sv",
"file_path": "/afPrxdEVh9uoSSIc0RVKMXPRHWm.jpg",
"vote_average": 0,
"vote_count": 0,
"width": 2000
},
{
"aspect_ratio": 0.667,
"height": 3000,
"iso_639_1": "sk",
"file_path": "/stF5ysfzd1X5xMuvOiv5k8rRiX3.jpg",
"vote_average": 0,
"vote_count": 0,
"width": 2000
}
]
}
}
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,927 @@
{
"data": {
"adult": false,
"backdrop_path": "/rV56FkcHkzHJcBOOqoCeSDnoBff.jpg",
"belongs_to_collection": null,
"budget": 0,
"genres": [
{ "id": 28, "name": "Action" },
{ "id": 18, "name": "Drama" }
],
"homepage": "",
"id": 990140,
"imdb_id": "tt22488024",
"original_language": "cn",
"original_title": "天龍八部之喬峰傳",
"overview": "Qiao Feng is the respected leader of a roving band of martial artists. After he is wrongfully accused of murder and subsequently exiled, Qiao Feng goes on the run in search of answers about his own mysterious origin story—and the unknown enemies working to destroy him from the shadows.",
"popularity": 522.83,
"poster_path": "/jGKCpt3zzbGZbgoza6HCvecqElM.jpg",
"production_companies": [
{ "id": 155372, "logo_path": null, "name": "Wishart Media Co., Ltd.", "origin_country": "" },
{ "id": 160005, "logo_path": null, "name": "Super Bullet Pictures", "origin_country": "HK" }
],
"production_countries": [
{ "iso_3166_1": "CN", "name": "China" },
{ "iso_3166_1": "HK", "name": "Hong Kong" }
],
"release_date": "2023-01-16",
"revenue": 159959,
"runtime": 130,
"spoken_languages": [
{ "english_name": "Cantonese", "iso_639_1": "cn", "name": "广州话 / 廣州話" },
{ "english_name": "Mandarin", "iso_639_1": "zh", "name": "普通话" }
],
"status": "Released",
"tagline": "When a warrior belongs nowhere, the enemy is everywhere.",
"title": "Sakra",
"video": false,
"vote_average": 6.552,
"vote_count": 87,
"credits": {
"cast": [
{
"adult": false,
"gender": 2,
"id": 1341,
"known_for_department": "Acting",
"name": "Donnie Yen",
"original_name": "Donnie Yen",
"popularity": 32.998,
"profile_path": "/hTlhrrZMj8hZVvD17j4KyAFWBHc.jpg",
"cast_id": 1,
"character": "Qiao Feng / Xiao Feng",
"credit_id": "62b0cf55ecc7e800f0fe0311",
"order": 0
},
{
"adult": false,
"gender": 1,
"id": 2085448,
"known_for_department": "Acting",
"name": "Yukee Chen",
"original_name": "Yukee Chen",
"popularity": 7.917,
"profile_path": "/3E8eXz1CJsE34LZsmQt1V3jH2Y5.jpg",
"cast_id": 4,
"character": "A Zhu",
"credit_id": "639572ec2cefc2007c1eb3c0",
"order": 1
},
{
"adult": false,
"gender": 1,
"id": 1397017,
"known_for_department": "Acting",
"name": "Liu Yase",
"original_name": "Liu Yase",
"popularity": 3.823,
"profile_path": "/2UBsASN6G37pjZtjl0Zse6S74y9.jpg",
"cast_id": 8,
"character": "A Zi",
"credit_id": "63980c59f5c8240083a9e015",
"order": 2
},
{
"adult": false,
"gender": 1,
"id": 84205,
"known_for_department": "Acting",
"name": "Kara Hui Ying-Hung",
"original_name": "Kara Hui Ying-Hung",
"popularity": 17.533,
"profile_path": "/6OV9kM62Y7M7EswtkpCThs0QAxg.jpg",
"cast_id": 9,
"character": "Ruan Xingzhu",
"credit_id": "63980c70f5c824007b890cd2",
"order": 3
},
{
"adult": false,
"gender": 2,
"id": 1800792,
"known_for_department": "Acting",
"name": "Wu Yue",
"original_name": "Wu Yue",
"popularity": 8.983,
"profile_path": "/hRePA3mh9mfAqX7SJ4rGxrNrxT7.jpg",
"cast_id": 7,
"character": "Murong Fu",
"credit_id": "63957308a0f1a200c880a34b",
"order": 4
},
{
"adult": false,
"gender": 2,
"id": 72732,
"known_for_department": "Acting",
"name": "Eddie Cheung",
"original_name": "Eddie Cheung",
"popularity": 5.704,
"profile_path": "/jTrBt3y43LsO8XYsQnWg8bdwsP2.jpg",
"cast_id": 14,
"character": "Duan Zhengchun",
"credit_id": "63980e36d05a0300cf2afd10",
"order": 5
},
{
"adult": false,
"gender": 1,
"id": 1255467,
"known_for_department": "Acting",
"name": "Grace Wong",
"original_name": "Grace Wong",
"popularity": 2.312,
"profile_path": "/Ab9GO6Awb183qaSP9VxlVNWZpFg.jpg",
"cast_id": 12,
"character": "Mrs. Ma",
"credit_id": "63980cd8d05a030094f1d7d3",
"order": 6
},
{
"adult": false,
"gender": 2,
"id": 1571926,
"known_for_department": "Acting",
"name": "Do Yuming",
"original_name": "Do Yuming",
"popularity": 3.349,
"profile_path": "/aqxa9aRrGOIiIcia0Vb3ErvXz4e.jpg",
"cast_id": 17,
"character": "Bai Shijing",
"credit_id": "63980fd28a88b20091ab7208",
"order": 7
},
{
"adult": false,
"gender": 2,
"id": 78877,
"known_for_department": "Acting",
"name": "Ray Lui",
"original_name": "Ray Lui",
"popularity": 5.367,
"profile_path": "/v6KV1Ib7ck9noPdwL6L2lAozeak.jpg",
"cast_id": 16,
"character": "Murong Bo",
"credit_id": "63980e6df5c824008bc95f42",
"order": 8
},
{
"adult": false,
"gender": 2,
"id": 1145614,
"known_for_department": "Directing",
"name": "Tsui Siu-Ming",
"original_name": "Tsui Siu-Ming",
"popularity": 1.31,
"profile_path": "/aY9b2ucIGylE3d7a1GNALk8qwH.jpg",
"cast_id": 15,
"character": "Jiu Mozhi",
"credit_id": "63980e5da1a9ba00a0003400",
"order": 9
},
{
"adult": false,
"gender": 1,
"id": 2961684,
"known_for_department": "Acting",
"name": "Cai Xiangyu",
"original_name": "Cai Xiangyu",
"popularity": 1.631,
"profile_path": "/9P9916rJ9SkiYBqrAckRsuO48FA.jpg",
"cast_id": 21,
"character": "A Bi",
"credit_id": "63cb7e60ea394900c827848a",
"order": 10
},
{
"adult": false,
"gender": 1,
"id": 1209782,
"known_for_department": "Acting",
"name": "Michelle Hu",
"original_name": "Michelle Hu",
"popularity": 8.5,
"profile_path": "/oNwNoLJg707G0HSIDnNU4mpaoIu.jpg",
"cast_id": 22,
"character": "Mrs. Xiao",
"credit_id": "63cb7e739a6435008def2fc7",
"order": 11
},
{
"adult": false,
"gender": 0,
"id": 3260046,
"known_for_department": "Acting",
"name": "Zhao Huawei",
"original_name": "Zhao Huawei",
"popularity": 0.6,
"profile_path": null,
"cast_id": 23,
"character": "Duan Yu",
"credit_id": "63cb7ea46d97e6007c9d47f2",
"order": 12
},
{
"adult": false,
"gender": 2,
"id": 1089434,
"known_for_department": "Acting",
"name": "Yu Kang",
"original_name": "Yu Kang",
"popularity": 4.673,
"profile_path": "/aga0SZgIsntO4ZNsOF28HBLMx3i.jpg",
"cast_id": 24,
"character": "You Ju",
"credit_id": "63cb7eba9a643500872aa4a4",
"order": 13
},
{
"adult": false,
"gender": 2,
"id": 1174692,
"known_for_department": "Acting",
"name": "Xu Xiangdong",
"original_name": "Xu Xiangdong",
"popularity": 2.684,
"profile_path": null,
"cast_id": 25,
"character": "Xuannan",
"credit_id": "63cb7ed0d363e500ba783604",
"order": 14
},
{
"adult": false,
"gender": 2,
"id": 65975,
"known_for_department": "Acting",
"name": "Yuen Cheung-Yan",
"original_name": "Yuen Cheung-Yan",
"popularity": 3.233,
"profile_path": "/oI1Q07u74Yod4t8K06aSvfEJIbH.jpg",
"cast_id": 26,
"character": "Xue Muhua",
"credit_id": "63cf408c0d2f5301d1ef7d31",
"order": 15
},
{
"adult": false,
"gender": 0,
"id": 3998591,
"known_for_department": "Acting",
"name": "Cheung Siu Fai",
"original_name": "Cheung Siu Fai",
"popularity": 0.6,
"profile_path": null,
"cast_id": 34,
"character": "",
"credit_id": "642fe90e9a643506f1afb11f",
"order": 16
},
{
"adult": false,
"gender": 0,
"id": 3998593,
"known_for_department": "Acting",
"name": "Cya Liu",
"original_name": "Cya Liu",
"popularity": 0.6,
"profile_path": null,
"cast_id": 35,
"character": "",
"credit_id": "642fe92531032500bd55bed7",
"order": 17
},
{
"adult": false,
"gender": 2,
"id": 1113443,
"known_for_department": "Acting",
"name": "Kenji Tanigaki",
"original_name": "Kenji Tanigaki",
"popularity": 3.134,
"profile_path": "/4WKEFXTK233yvrRvjA6TLIQiCn0.jpg",
"cast_id": 37,
"character": "",
"credit_id": "642fe970e92d83011306e9c7",
"order": 18
},
{
"adult": false,
"gender": 0,
"id": 3183831,
"known_for_department": "Acting",
"name": "Hua Yan",
"original_name": "Hua Yan",
"popularity": 0.6,
"profile_path": null,
"cast_id": 38,
"character": "Bandit",
"credit_id": "642fe9bae92d8300b6e41abd",
"order": 19
}
],
"crew": [
{
"adult": false,
"gender": 2,
"id": 1341,
"known_for_department": "Acting",
"name": "Donnie Yen",
"original_name": "Donnie Yen",
"popularity": 32.998,
"profile_path": "/hTlhrrZMj8hZVvD17j4KyAFWBHc.jpg",
"credit_id": "639572d2a1a9ba00a0fef209",
"department": "Directing",
"job": "Director"
},
{
"adult": false,
"gender": 2,
"id": 1341,
"known_for_department": "Acting",
"name": "Donnie Yen",
"original_name": "Donnie Yen",
"popularity": 32.998,
"profile_path": "/hTlhrrZMj8hZVvD17j4KyAFWBHc.jpg",
"credit_id": "63980c9679b3d400a0bc13f1",
"department": "Production",
"job": "Producer"
},
{
"adult": false,
"gender": 2,
"id": 64430,
"known_for_department": "Camera",
"name": "Chi Ying Chan",
"original_name": "Chi Ying Chan",
"popularity": 1.204,
"profile_path": "/yDChYg2NSVBYAmGdoyTDznaIfSv.jpg",
"credit_id": "63981028f5c82400b783039a",
"department": "Camera",
"job": "Director of Photography"
},
{
"adult": false,
"gender": 2,
"id": 548474,
"known_for_department": "Writing",
"name": "Wong Jing",
"original_name": "Wong Jing",
"popularity": 4.649,
"profile_path": "/gMmaDRst3OwnY1wClKt541AmslD.jpg",
"credit_id": "63980c892cefc20084b6093a",
"department": "Production",
"job": "Producer"
},
{
"adult": false,
"gender": 0,
"id": 551565,
"known_for_department": "Art",
"name": "Lau Sai-Wan",
"original_name": "Lau Sai-Wan",
"popularity": 0.6,
"profile_path": null,
"credit_id": "639810a5a1a9ba009430b5f2",
"department": "Art",
"job": "Art Direction"
},
{
"adult": false,
"gender": 1,
"id": 1006504,
"known_for_department": "Writing",
"name": "Chen Li",
"original_name": "Chen Li",
"popularity": 1.183,
"profile_path": "/uIkAFpDNsAL5sYmlartPNoV2BWn.jpg",
"credit_id": "64288650c5840d00d58e3c34",
"department": "Writing",
"job": "Writer"
},
{
"adult": false,
"gender": 2,
"id": 1113443,
"known_for_department": "Acting",
"name": "Kenji Tanigaki",
"original_name": "Kenji Tanigaki",
"popularity": 3.134,
"profile_path": "/4WKEFXTK233yvrRvjA6TLIQiCn0.jpg",
"credit_id": "62b0cfb19c24fc0061b28020",
"department": "Directing",
"job": "Action Director"
},
{
"adult": false,
"gender": 2,
"id": 1415282,
"known_for_department": "Directing",
"name": "Kam Ka-Wai",
"original_name": "Kam Ka-Wai",
"popularity": 1.821,
"profile_path": "/gsPOd7NYzugZJwnEI5DokM6plQC.jpg",
"credit_id": "64288624c0442901f0024683",
"department": "Directing",
"job": "Director"
},
{
"adult": false,
"gender": 2,
"id": 2095747,
"known_for_department": "Acting",
"name": "Andrew Yan Hua",
"original_name": "Andrew Yan Hua",
"popularity": 1.052,
"profile_path": null,
"credit_id": "6398107bd05a0300ae5105b3",
"department": "Directing",
"job": "Action Director"
},
{
"adult": false,
"gender": 2,
"id": 2195223,
"known_for_department": "Directing",
"name": "Leping Shen",
"original_name": "Leping Shen",
"popularity": 0.6,
"profile_path": "/ocdkTboTAdk6BkJKO2Wrq4yLoto.jpg",
"credit_id": "6428866a960cde0103a4b5be",
"department": "Writing",
"job": "Writer"
},
{
"adult": false,
"gender": 0,
"id": 2552279,
"known_for_department": "Directing",
"name": "Wei Zhu",
"original_name": "Wei Zhu",
"popularity": 0.98,
"profile_path": "/1hcEJ4rXam8i74RjTjfn6JKcSIo.jpg",
"credit_id": "642886880f3655011078cc3e",
"department": "Writing",
"job": "Writer"
},
{
"adult": false,
"gender": 0,
"id": 3113929,
"known_for_department": "Production",
"name": "Zhu Weijie",
"original_name": "Zhu Weijie",
"popularity": 0.6,
"profile_path": null,
"credit_id": "63980d8ed05a0300ae5103a0",
"department": "Production",
"job": "Executive Producer"
},
{
"adult": false,
"gender": 0,
"id": 3391253,
"known_for_department": "Directing",
"name": "Sheng Lingzhi",
"original_name": "Sheng Lingzhi",
"popularity": 0.6,
"profile_path": null,
"credit_id": "6428865e01b1ca0097fd97c6",
"department": "Writing",
"job": "Writer"
},
{
"adult": false,
"gender": 0,
"id": 3989726,
"known_for_department": "Writing",
"name": "He Ben",
"original_name": "He Ben",
"popularity": 0.668,
"profile_path": null,
"credit_id": "64288644c04429026b13431a",
"department": "Writing",
"job": "Writer"
},
{
"adult": false,
"gender": 0,
"id": 3989729,
"known_for_department": "Writing",
"name": "Xu Yifan",
"original_name": "Xu Yifan",
"popularity": 0.6,
"profile_path": null,
"credit_id": "6428867a960cde00e0bcdb7d",
"department": "Writing",
"job": "Writer"
}
]
},
"videos": {
"results": [
{
"iso_639_1": "en",
"iso_3166_1": "US",
"name": "Official US Trailer",
"key": "aHP_pyGtFIk",
"site": "YouTube",
"size": 1080,
"type": "Trailer",
"official": true,
"published_at": "2023-03-23T17:09:04.000Z",
"id": "641e49dcc613ce01031f8b85"
},
{
"iso_639_1": "en",
"iso_3166_1": "US",
"name": "Main Trailer",
"key": "es5NAYPdcdI",
"site": "YouTube",
"size": 1080,
"type": "Trailer",
"official": true,
"published_at": "2023-01-12T10:00:30.000Z",
"id": "640a298154f6eb00993d3ebf"
}
]
},
"images": {
"backdrops": [
{
"aspect_ratio": 1.778,
"height": 2160,
"iso_639_1": null,
"file_path": "/rV56FkcHkzHJcBOOqoCeSDnoBff.jpg",
"vote_average": 5.312,
"vote_count": 1,
"width": 3840
},
{
"aspect_ratio": 1.778,
"height": 1080,
"iso_639_1": null,
"file_path": "/skY1yDFcLF4h6CYDxndr5jHJNof.jpg",
"vote_average": 5.172,
"vote_count": 1,
"width": 1920
},
{
"aspect_ratio": 1.778,
"height": 1080,
"iso_639_1": null,
"file_path": "/zS3ngMx0IJGzSUlAJ5u40utdCFK.jpg",
"vote_average": 5.172,
"vote_count": 1,
"width": 1920
},
{
"aspect_ratio": 1.778,
"height": 1080,
"iso_639_1": null,
"file_path": "/oREkJ5uPIryJz0zWMASkGVLzeIc.jpg",
"vote_average": 5.106,
"vote_count": 2,
"width": 1920
},
{
"aspect_ratio": 1.778,
"height": 2160,
"iso_639_1": "en",
"file_path": "/qAL0fwjZCQ41TwybgERAAUp4kWA.jpg",
"vote_average": 0,
"vote_count": 0,
"width": 3840
},
{
"aspect_ratio": 1.778,
"height": 2160,
"iso_639_1": null,
"file_path": "/bBERGgCqgUPzriFxsVrXccINprn.jpg",
"vote_average": 0,
"vote_count": 0,
"width": 3840
},
{
"aspect_ratio": 1.778,
"height": 2160,
"iso_639_1": "fr",
"file_path": "/v4E3Gb7QikastXcvKzvn519bM1m.jpg",
"vote_average": 0,
"vote_count": 0,
"width": 3840
}
],
"logos": [
{
"aspect_ratio": 4.046,
"height": 194,
"iso_639_1": "en",
"file_path": "/pqu3S5zlYRt9oPXmC4OI1r4dml5.png",
"vote_average": 5.312,
"vote_count": 1,
"width": 785
},
{
"aspect_ratio": 1.733,
"height": 288,
"iso_639_1": "en",
"file_path": "/jWexdriLJE0kFXG4Nct7C0tSnfJ.png",
"vote_average": 5.106,
"vote_count": 2,
"width": 499
},
{
"aspect_ratio": 1.691,
"height": 615,
"iso_639_1": "zh",
"file_path": "/slL3b5hNslfrjdM4qlXn3XhJcak.png",
"vote_average": 0,
"vote_count": 0,
"width": 1040
},
{
"aspect_ratio": 1.878,
"height": 147,
"iso_639_1": "zh",
"file_path": "/cd24lYjAb7dQRS7l4UrIs9D81go.png",
"vote_average": 0,
"vote_count": 0,
"width": 276
},
{
"aspect_ratio": 2.555,
"height": 1286,
"iso_639_1": "fr",
"file_path": "/4heIx9YFADRbnfkSzlFS6LVGTfT.png",
"vote_average": 0,
"vote_count": 0,
"width": 3286
},
{
"aspect_ratio": 2.497,
"height": 1273,
"iso_639_1": "fr",
"file_path": "/fn2o38gQPPqqmlH2qLyk4wP9GJT.png",
"vote_average": 0,
"vote_count": 0,
"width": 3179
}
],
"posters": [
{
"aspect_ratio": 0.667,
"height": 3000,
"iso_639_1": "cn",
"file_path": "/vvWyOCmBAND2p9UwaXZdALIDd2W.jpg",
"vote_average": 5.384,
"vote_count": 2,
"width": 2000
},
{
"aspect_ratio": 0.672,
"height": 2048,
"iso_639_1": "en",
"file_path": "/jGKCpt3zzbGZbgoza6HCvecqElM.jpg",
"vote_average": 5.318,
"vote_count": 3,
"width": 1376
},
{
"aspect_ratio": 0.71,
"height": 1600,
"iso_639_1": "cn",
"file_path": "/vksLBSmHahKD9F30vIrm0S7JsSO.jpg",
"vote_average": 5.312,
"vote_count": 1,
"width": 1136
},
{
"aspect_ratio": 0.667,
"height": 3000,
"iso_639_1": "zh",
"file_path": "/zr28ZaTpZeB7ACFVIoa4YuxFHgh.jpg",
"vote_average": 5.312,
"vote_count": 1,
"width": 2000
},
{
"aspect_ratio": 0.667,
"height": 2340,
"iso_639_1": "zh",
"file_path": "/k20PICIsiYMkD425UASSXs12M3.jpg",
"vote_average": 5.312,
"vote_count": 1,
"width": 1560
},
{
"aspect_ratio": 0.667,
"height": 3000,
"iso_639_1": "cn",
"file_path": "/rafCyitNRMQUHDIVh3abWZRWofO.jpg",
"vote_average": 5.312,
"vote_count": 1,
"width": 2000
},
{
"aspect_ratio": 0.667,
"height": 2100,
"iso_639_1": "de",
"file_path": "/b4A9L61eJfLL2eWPjsfwhDuzDsP.jpg",
"vote_average": 5.312,
"vote_count": 1,
"width": 1400
},
{
"aspect_ratio": 0.667,
"height": 3000,
"iso_639_1": "de",
"file_path": "/lEWeNdbPuJIUON6qUwwvRcYNgSU.jpg",
"vote_average": 5.246,
"vote_count": 2,
"width": 2000
},
{
"aspect_ratio": 0.667,
"height": 3000,
"iso_639_1": "fr",
"file_path": "/qGhdGdocth1csUlEnPEmYDfEmwY.jpg",
"vote_average": 5.238,
"vote_count": 0,
"width": 2000
},
{
"aspect_ratio": 0.667,
"height": 1600,
"iso_639_1": "de",
"file_path": "/zFRCKPsJxuQqdtysUD7UaySnxKC.jpg",
"vote_average": 5.106,
"vote_count": 2,
"width": 1067
},
{
"aspect_ratio": 0.705,
"height": 1064,
"iso_639_1": "cn",
"file_path": "/vPRZUtW2tQZ0JzwqUcS739qDfOv.jpg",
"vote_average": 0,
"vote_count": 0,
"width": 750
},
{
"aspect_ratio": 0.667,
"height": 2815,
"iso_639_1": "ko",
"file_path": "/rl6lMKv6XRPPOgMTcTmZWSsEsLH.jpg",
"vote_average": 0,
"vote_count": 0,
"width": 1877
},
{
"aspect_ratio": 0.666,
"height": 2067,
"iso_639_1": "zh",
"file_path": "/dvlaQWBoZYmgHrG9r4V5DWn7e4N.jpg",
"vote_average": 0,
"vote_count": 0,
"width": 1377
},
{
"aspect_ratio": 0.705,
"height": 1532,
"iso_639_1": "zh",
"file_path": "/vNpAREC0oLWUx1F7NWSdGO89Qaf.jpg",
"vote_average": 0,
"vote_count": 0,
"width": 1080
},
{
"aspect_ratio": 0.667,
"height": 1711,
"iso_639_1": "ko",
"file_path": "/fmcRd957yQnlyEFltODkScqldKr.jpg",
"vote_average": 0,
"vote_count": 0,
"width": 1141
},
{
"aspect_ratio": 0.672,
"height": 2048,
"iso_639_1": "fr",
"file_path": "/1d4Iru6pLYESE1DsE8BVxK5OwRm.jpg",
"vote_average": 0,
"vote_count": 0,
"width": 1376
},
{
"aspect_ratio": 0.667,
"height": 2400,
"iso_639_1": "zh",
"file_path": "/lI3gD04BXUnB9ZhPmceeAVmnwHp.jpg",
"vote_average": 0,
"vote_count": 0,
"width": 1600
},
{
"aspect_ratio": 0.667,
"height": 1600,
"iso_639_1": "en",
"file_path": "/2vA3CqwZ01LUsEaYRz2ZY6Om9xi.jpg",
"vote_average": 0,
"vote_count": 0,
"width": 1067
},
{
"aspect_ratio": 0.667,
"height": 1500,
"iso_639_1": "en",
"file_path": "/uSmqyGyrjP1FF5UpxryUsSdQ4w0.jpg",
"vote_average": 0,
"vote_count": 0,
"width": 1000
},
{
"aspect_ratio": 0.667,
"height": 1500,
"iso_639_1": "en",
"file_path": "/7JzNqNnisJnKH69mYuXNedznAAH.jpg",
"vote_average": 0,
"vote_count": 0,
"width": 1000
},
{
"aspect_ratio": 0.667,
"height": 1500,
"iso_639_1": "en",
"file_path": "/o6229QNb9FHwWBCemZxM8mCBDgV.jpg",
"vote_average": 0,
"vote_count": 0,
"width": 1000
},
{
"aspect_ratio": 0.667,
"height": 1500,
"iso_639_1": "en",
"file_path": "/7UyeEpMQXp5zlzSVHif8ZWDE2tA.jpg",
"vote_average": 0,
"vote_count": 0,
"width": 1000
},
{
"aspect_ratio": 0.666,
"height": 1367,
"iso_639_1": "en",
"file_path": "/xoznyg9SNXjHPwT9kMMrPr6vW34.jpg",
"vote_average": 0,
"vote_count": 0,
"width": 911
},
{
"aspect_ratio": 0.667,
"height": 2100,
"iso_639_1": "en",
"file_path": "/aS3mnTkt6cnPcndb0l3F0J7GTDK.jpg",
"vote_average": 0,
"vote_count": 0,
"width": 1400
},
{
"aspect_ratio": 0.667,
"height": 3000,
"iso_639_1": "tr",
"file_path": "/zP9mNbn55fNGdbHOAqzMt07aN4s.jpg",
"vote_average": 0,
"vote_count": 0,
"width": 2000
},
{
"aspect_ratio": 0.667,
"height": 1500,
"iso_639_1": "fr",
"file_path": "/tObrbSUlTGurumll1SaIeVf14TT.jpg",
"vote_average": 0,
"vote_count": 0,
"width": 1000
},
{
"aspect_ratio": 0.667,
"height": 1500,
"iso_639_1": "fr",
"file_path": "/rvy5WHZMY8YEaCmJjNvD9DW73AR.jpg",
"vote_average": 0,
"vote_count": 0,
"width": 1000
},
{
"aspect_ratio": 0.667,
"height": 3000,
"iso_639_1": "fr",
"file_path": "/hCsXU4l8NdhmQTaLknzg9em73tF.jpg",
"vote_average": 0,
"vote_count": 0,
"width": 2000
}
]
}
}
}

View file

@ -0,0 +1,36 @@
---
import '../styles/styles.css';
import { ViewTransitions } from 'astro:transitions';
import Footer from '../components/Footer.astro';
import Nav from '../components/Nav.astro';
export interface Props {
title: string;
}
const { title } = Astro.props as Props;
---
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width" />
<link rel="icon" type="image/x-icon" href="/favicon.ico" />
<meta name="generator" content={Astro.generator} />
<meta name="view-transition" content="same-origin" />
<title>{title}</title>
<ViewTransitions />
</head>
<body class="font-sans bg-gray-900 text-white">
<div class="h-screen overflow-hidden flex flex-col">
<Nav />
<div id="container" class="h-full flex-1 overflow-y-auto">
<div id="content">
<slot />
</div>
<Footer />
</div>
</div>
</body>
</html>

View file

@ -0,0 +1,8 @@
---
import Layout from '../layouts/Layout.astro';
import MovieList from '../components/MovieList.astro';
---
<Layout title="Movies List">
<MovieList />
</Layout>

View file

@ -0,0 +1,14 @@
---
import Layout from '../../layouts/Layout.astro';
import MovieDetails from '../../components/MovieDetails.astro';
import { getDataEntryById } from 'astro:content';
// Data collection bug?
const id: any = '/src/content/movies/' + Astro.params.id;
const result = await getDataEntryById('movies', id);
const data = result.data.data;
---
<Layout title={`${data.title} on Movies List`}>
<MovieDetails data={data} />
</Layout>

View file

@ -0,0 +1,327 @@
{
"page": 1,
"results": [
{
"adult": false,
"backdrop_path": "/iIvQnZyzgx9TkbrOgcXx0p7aLiq.jpg",
"genre_ids": [27, 53],
"id": 1008042,
"original_language": "en",
"original_title": "Talk to Me",
"overview": "When a group of friends discover how to conjure spirits using an embalmed hand, they become hooked on the new thrill, until one of them goes too far and unleashes terrifying supernatural forces.",
"popularity": 2292.177,
"poster_path": "/kdPMUMJzyYAc4roD52qavX0nLIC.jpg",
"release_date": "2023-07-26",
"title": "Talk to Me",
"video": false,
"vote_average": 7.3,
"vote_count": 686
},
{
"adult": false,
"backdrop_path": "/ctMserH8g2SeOAnCw5gFjdQF8mo.jpg",
"genre_ids": [35, 12, 14],
"id": 346698,
"original_language": "en",
"original_title": "Barbie",
"overview": "Barbie and Ken are having the time of their lives in the colorful and seemingly perfect world of Barbie Land. However, when they get a chance to go to the real world, they soon discover the joys and perils of living among humans.",
"popularity": 1899.184,
"poster_path": "/iuFNMS8U5cb6xfzi51Dbkovj7vM.jpg",
"release_date": "2023-07-19",
"title": "Barbie",
"video": false,
"vote_average": 7.3,
"vote_count": 4757
},
{
"adult": false,
"backdrop_path": "/4XM8DUTQb3lhLemJC51Jx4a2EuA.jpg",
"genre_ids": [28, 80, 53],
"id": 385687,
"original_language": "en",
"original_title": "Fast X",
"overview": "Over many missions and against impossible odds, Dom Toretto and his family have outsmarted, out-nerved and outdriven every foe in their path. Now, they confront the most lethal opponent they've ever faced: A terrifying threat emerging from the shadows of the past who's fueled by blood revenge, and who is determined to shatter this family and destroy everything—and everyone—that Dom loves, forever.",
"popularity": 1973.052,
"poster_path": "/fiVW06jE7z9YnO4trhaMEdclSiC.jpg",
"release_date": "2023-05-17",
"title": "Fast X",
"video": false,
"vote_average": 7.3,
"vote_count": 3749
},
{
"adult": false,
"backdrop_path": "/8pjWz2lt29KyVGoq1mXYu6Br7dE.jpg",
"genre_ids": [28, 878, 27],
"id": 615656,
"original_language": "en",
"original_title": "Meg 2: The Trench",
"overview": "An exploratory dive into the deepest depths of the ocean of a daring research team spirals into chaos when a malevolent mining operation threatens their mission and forces them into a high-stakes battle for survival.",
"popularity": 1804.581,
"poster_path": "/4m1Au3YkjqsxF8iwQy0fPYSxE0h.jpg",
"release_date": "2023-08-02",
"title": "Meg 2: The Trench",
"video": false,
"vote_average": 7,
"vote_count": 1823
},
{
"adult": false,
"backdrop_path": "/c6Splshb8lb2Q9OvUfhpqXl7uP0.jpg",
"genre_ids": [28, 53],
"id": 717930,
"original_language": "en",
"original_title": "Kandahar",
"overview": "After his mission is exposed, an undercover CIA operative stuck deep in hostile territory in Afghanistan must fight his way out, alongside his Afghan translator, to an extraction point in Kandahar, all whilst avoiding elite enemy forces and foreign spies tasked with hunting them down.",
"popularity": 1206.966,
"poster_path": "/lCanGgsqF4xD2WA5NF8PWeT3IXd.jpg",
"release_date": "2023-05-25",
"title": "Kandahar",
"video": false,
"vote_average": 6.8,
"vote_count": 507
},
{
"adult": false,
"backdrop_path": "/53z2fXEKfnNg2uSOPss2unPBGX1.jpg",
"genre_ids": [27, 9648, 53],
"id": 968051,
"original_language": "en",
"original_title": "The Nun II",
"overview": "In 1956 France, a priest is violently murdered, and Sister Irene begins to investigate. She once again comes face-to-face with a powerful evil.",
"popularity": 1296.77,
"poster_path": "/5gzzkR7y3hnY8AD1wXjCnVlHba5.jpg",
"release_date": "2023-09-06",
"title": "The Nun II",
"video": false,
"vote_average": 6.7,
"vote_count": 229
},
{
"adult": false,
"backdrop_path": "/4fLZUr1e65hKPPVw0R3PmKFKxj1.jpg",
"genre_ids": [16, 35, 10751, 14, 10749],
"id": 976573,
"original_language": "en",
"original_title": "Elemental",
"overview": "In a city where fire, water, land and air residents live together, a fiery young woman and a go-with-the-flow guy will discover something elemental: how much they have in common.",
"popularity": 953.333,
"poster_path": "/4Y1WNkd88JXmGfhtWR7dmDAo1T2.jpg",
"release_date": "2023-06-14",
"title": "Elemental",
"video": false,
"vote_average": 7.8,
"vote_count": 2182
},
{
"adult": false,
"backdrop_path": "/H6j5smdpRqP9a8UnhWp6zfl0SC.jpg",
"genre_ids": [28, 878, 12],
"id": 565770,
"original_language": "en",
"original_title": "Blue Beetle",
"overview": "Recent college grad Jaime Reyes returns home full of aspirations for his future, only to find that home is not quite as he left it. As he searches to find his purpose in the world, fate intervenes when Jaime unexpectedly finds himself in possession of an ancient relic of alien biotechnology: the Scarab.",
"popularity": 1007.105,
"poster_path": "/vNfL4DYnonltukBrrgMmw94zMYL.jpg",
"release_date": "2023-08-16",
"title": "Blue Beetle",
"video": false,
"vote_average": 7.2,
"vote_count": 541
},
{
"adult": false,
"backdrop_path": "/9m161GawbY3cWxe6txd1NOHTjd0.jpg",
"genre_ids": [878, 12, 28, 14],
"id": 335977,
"original_language": "en",
"original_title": "Indiana Jones and the Dial of Destiny",
"overview": "Finding himself in a new era, and approaching retirement, Indy wrestles with fitting into a world that seems to have outgrown him. But as the tentacles of an all-too-familiar evil return in the form of an old rival, Indy must don his hat and pick up his whip once more to make sure an ancient and powerful artifact doesn't fall into the wrong hands.",
"popularity": 804.982,
"poster_path": "/Af4bXE63pVsb2FtbW8uYIyPBadD.jpg",
"release_date": "2023-06-28",
"title": "Indiana Jones and the Dial of Destiny",
"video": false,
"vote_average": 6.7,
"vote_count": 1650
},
{
"adult": false,
"backdrop_path": "/jkKVLzLWjSvTnc84VzeljhSy6j8.jpg",
"genre_ids": [10749, 18],
"id": 820525,
"original_language": "en",
"original_title": "After Everything",
"overview": "Besieged by writers block and the crushing breakup with Tessa, Hardin travels to Portugal in search of a woman he wronged in the past and to find himself. Hoping to win back Tessa, he realizes he needs to change his ways before he can make the ultimate commitment.",
"popularity": 650.272,
"poster_path": "/gZLGCibvFY4zmt8sWUZcbBTHRtk.jpg",
"release_date": "2023-09-13",
"title": "After Everything",
"video": false,
"vote_average": 6.4,
"vote_count": 27
},
{
"adult": false,
"backdrop_path": "/waBWlJlMpyFb7STkFHfFvJKgwww.jpg",
"genre_ids": [28, 18],
"id": 678512,
"original_language": "en",
"original_title": "Sound of Freedom",
"overview": "The story of Tim Ballard, a former US government agent, who quits his job in order to devote his life to rescuing children from global sex traffickers.",
"popularity": 668.456,
"poster_path": "/kSf9svfL2WrKeuK8W08xeR5lTn8.jpg",
"release_date": "2023-07-03",
"title": "Sound of Freedom",
"video": false,
"vote_average": 8,
"vote_count": 458
},
{
"adult": false,
"backdrop_path": "/iiXliCeykkzmJ0Eg9RYJ7F2CWSz.jpg",
"genre_ids": [28, 9648, 53, 80],
"id": 762430,
"original_language": "en",
"original_title": "Retribution",
"overview": "When a mysterious caller puts a bomb under his car seat, Matt Turner begins a high-speed chase across the city to complete a specific series of tasks. With his kids trapped in the back seat and a bomb that will explode if they get out of the car, a normal commute becomes a twisted game of life or death as Matt follows the stranger's increasingly dangerous instructions in a race against time to save his family.",
"popularity": 702.724,
"poster_path": "/oUmmY7QWWn7OhKlcPOnirHJpP1F.jpg",
"release_date": "2023-08-23",
"title": "Retribution",
"video": false,
"vote_average": 6.6,
"vote_count": 130
},
{
"adult": false,
"backdrop_path": "/2vFuG6bWGyQUzYS9d69E5l85nIz.jpg",
"genre_ids": [28, 12, 878],
"id": 667538,
"original_language": "en",
"original_title": "Transformers: Rise of the Beasts",
"overview": "When a new threat capable of destroying the entire planet emerges, Optimus Prime and the Autobots must team up with a powerful faction known as the Maximals. With the fate of humanity hanging in the balance, humans Noah and Elena will do whatever it takes to help the Transformers as they engage in the ultimate battle to save Earth.",
"popularity": 650.789,
"poster_path": "/gPbM0MK8CP8A174rmUwGsADNYKD.jpg",
"release_date": "2023-06-06",
"title": "Transformers: Rise of the Beasts",
"video": false,
"vote_average": 7.5,
"vote_count": 3189
},
{
"adult": false,
"backdrop_path": "/w2nFc2Rsm93PDkvjY4LTn17ePO0.jpg",
"genre_ids": [16, 35, 28],
"id": 614930,
"original_language": "en",
"original_title": "Teenage Mutant Ninja Turtles: Mutant Mayhem",
"overview": "After years of being sheltered from the human world, the Turtle brothers set out to win the hearts of New Yorkers and be accepted as normal teenagers through heroic acts. Their new friend April O'Neil helps them take on a mysterious crime syndicate, but they soon get in over their heads when an army of mutants is unleashed upon them.",
"popularity": 644.874,
"poster_path": "/oupWWrVuCgNEa5GcjdkpjCYbx2X.jpg",
"release_date": "2023-07-31",
"title": "Teenage Mutant Ninja Turtles: Mutant Mayhem",
"video": false,
"vote_average": 7.3,
"vote_count": 541
},
{
"adult": false,
"backdrop_path": "/yF1eOkaYvwiORauRCPWznV9xVvi.jpg",
"genre_ids": [28, 12, 878],
"id": 298618,
"original_language": "en",
"original_title": "The Flash",
"overview": "When his attempt to save his family inadvertently alters the future, Barry Allen becomes trapped in a reality in which General Zod has returned and there are no Super Heroes to turn to. In order to save the world that he is in and return to the future that he knows, Barry's only hope is to race for his life. But will making the ultimate sacrifice be enough to reset the universe?",
"popularity": 561.181,
"poster_path": "/rktDFPbfHfUbArZ6OOOKsXcv0Bm.jpg",
"release_date": "2023-06-13",
"title": "The Flash",
"video": false,
"vote_average": 6.9,
"vote_count": 2873
},
{
"adult": false,
"backdrop_path": "/4HodYYKEIsGOdinkGi2Ucz6X9i0.jpg",
"genre_ids": [16, 28, 12],
"id": 569094,
"original_language": "en",
"original_title": "Spider-Man: Across the Spider-Verse",
"overview": "After reuniting with Gwen Stacy, Brooklyns full-time, friendly neighborhood Spider-Man is catapulted across the Multiverse, where he encounters the Spider Society, a team of Spider-People charged with protecting the Multiverses very existence. But when the heroes clash on how to handle a new threat, Miles finds himself pitted against the other Spiders and must set out on his own to save those he loves most.",
"popularity": 842.076,
"poster_path": "/8Vt6mWEReuy4Of61Lnj5Xj704m8.jpg",
"release_date": "2023-05-31",
"title": "Spider-Man: Across the Spider-Verse",
"video": false,
"vote_average": 8.5,
"vote_count": 4261
},
{
"adult": false,
"backdrop_path": "/9fOfsVHZHig6MHPHczv0zMY6cKc.jpg",
"genre_ids": [28, 53, 10752, 18],
"id": 1880,
"original_language": "en",
"original_title": "Red Dawn",
"overview": "It is the dawn of World War III. In mid-western America, a group of teenagers band together to defend their town—and their country—from invading Soviet forces.",
"popularity": 579.024,
"poster_path": "/a2GkHcioc2QEFJbQk1NTB85u3vD.jpg",
"release_date": "1984-08-10",
"title": "Red Dawn",
"video": false,
"vote_average": 6.3,
"vote_count": 670
},
{
"adult": false,
"backdrop_path": "/3mYCjwll5RG342Dz1f8HcnT8tV.jpg",
"genre_ids": [28, 80],
"id": 606403,
"original_language": "ko",
"original_title": "특송",
"overview": "Eun-ha, who is a normal junkyard employee, secretly works as a delivery clerk that deals with unusual delivery requests. One day, Eun-ha heads to Seoul to pick up a client who is involved in a gambling crime that wants to flee overseas. However, Eun-ha meets the client's young son at the pick-up point, instead of the client himself. Kyeong-pil, a current police officer who is actually masterminding the whole gambling crime, chases after the missing child who has the security key to the bank account that holds 30 million dollars.",
"popularity": 525.582,
"poster_path": "/fYT7JB4sU1XXeawEXOdQ3TtkFB2.jpg",
"release_date": "2022-01-12",
"title": "Special Delivery",
"video": false,
"vote_average": 6.9,
"vote_count": 105
},
{
"adult": false,
"backdrop_path": "/rV56FkcHkzHJcBOOqoCeSDnoBff.jpg",
"genre_ids": [28, 18],
"id": 990140,
"original_language": "cn",
"original_title": "天龍八部之喬峰傳",
"overview": "Qiao Feng is the respected leader of a roving band of martial artists. After he is wrongfully accused of murder and subsequently exiled, Qiao Feng goes on the run in search of answers about his own mysterious origin story—and the unknown enemies working to destroy him from the shadows.",
"popularity": 522.83,
"poster_path": "/jGKCpt3zzbGZbgoza6HCvecqElM.jpg",
"release_date": "2023-01-16",
"title": "Sakra",
"video": false,
"vote_average": 6.6,
"vote_count": 86
},
{
"adult": false,
"backdrop_path": "/4wVFtesa5YEWuAUHRcxoCN1Y1uN.jpg",
"genre_ids": [28, 53],
"id": 1085218,
"original_language": "da",
"original_title": "Underverden 2",
"overview": "Seven years ago, Zaid went to war against the Copenhagen underworld to avenge his dead brother. His identity as a respected doctor of cardiology and life as a family man is but a fading dream, and in prison Zaid suffers the loss of his son Noah, whom he barely knows. When a police agent approaches Zaid and offers him a deal to be released in exchange for infiltrating the Copenhagen underworld, he sees his chance to reclaim the remnants of the family life he left behind. But everything has a price, and Zaid realizes that he has now seriously endangered his son's life. After all, once you become part of the underworld, is there any way out?",
"popularity": 524.476,
"poster_path": "/c8B4DsVcFVDLVmbpHMHU3RjLNAV.jpg",
"release_date": "2023-04-13",
"title": "Darkland: The Return",
"video": false,
"vote_average": 6.2,
"vote_count": 59
}
],
"total_pages": 40154,
"total_results": 803062
}

View file

@ -0,0 +1,254 @@
import {
getNavigationType,
getPathId,
isBackNavigation,
shouldNotIntercept,
updateTheDOMSomehow,
useTvFragment,
} from './utils';
// View Transitions support cross-document navigations.
// Should compare performace.
// https://github.com/WICG/view-transitions/blob/main/explainer.md#cross-document-same-origin-transitions
// https://github.com/WICG/view-transitions/blob/main/explainer.md#script-events
function shouldDisableSpa() {
return false;
}
navigation.addEventListener('navigate', (navigateEvent) => {
if (shouldDisableSpa()) return;
if (shouldNotIntercept(navigateEvent)) return;
const toUrl = new URL(navigateEvent.destination.url);
const toPath = toUrl.pathname;
const fromPath = location.pathname;
const navigationType = getNavigationType(fromPath, toPath);
if (location.origin !== toUrl.origin) return;
switch (navigationType) {
case 'home-to-movie':
case 'tv-to-show':
handleHomeToMovieTransition(navigateEvent, getPathId(toPath));
break;
case 'movie-to-home':
case 'show-to-tv':
handleMovieToHomeTransition(navigateEvent, getPathId(fromPath));
break;
case 'movie-to-person':
handleMovieToPersonTransition(navigateEvent, getPathId(fromPath), getPathId(toPath));
break;
case 'person-to-movie':
case 'person-to-show':
handlePersonToMovieTransition(navigateEvent, getPathId(fromPath), getPathId(toPath));
break;
default:
return;
}
});
// TODO: https://developer.chrome.com/docs/web-platform/view-transitions/#transitions-as-an-enhancement
function handleHomeToMovieTransition(navigateEvent, movieId) {
navigateEvent.intercept({
async handler() {
const fragmentUrl = useTvFragment(navigateEvent)
? '/fragments/TvDetails'
: '/fragments/MovieDetails';
const response = await fetch(`${fragmentUrl}/${movieId}`);
const data = await response.text();
if (!document.startViewTransition) {
updateTheDOMSomehow(data);
return;
}
const thumbnail = document.getElementById(`movie-poster-${movieId}`);
if (thumbnail) {
thumbnail.style.viewTransitionName = 'movie-poster';
}
const transition = document.startViewTransition(() => {
if (thumbnail) {
thumbnail.style.viewTransitionName = '';
}
document.getElementById('container').scrollTop = 0;
updateTheDOMSomehow(data);
});
await transition.finished;
},
});
}
function handleMovieToHomeTransition(navigateEvent, movieId) {
navigateEvent.intercept({
scroll: 'manual',
async handler() {
const fragmentUrl = useTvFragment(navigateEvent)
? '/fragments/TvList'
: '/fragments/MovieList';
const response = await fetch(fragmentUrl);
const data = await response.text();
if (!document.startViewTransition) {
updateTheDOMSomehow(data);
return;
}
const tempHomePage = document.createElement('div');
const moviePoster = document.getElementById(`movie-poster`);
let thumbnail;
// If the movie poster is not in the home page, removes the transition style so that
// the poster doesn't stay on the page while transitioning
tempHomePage.innerHTML = data;
if (!tempHomePage.querySelector(`#movie-poster-${movieId}`)) {
moviePoster?.classList.remove('movie-poster');
}
const transition = document.startViewTransition(() => {
updateTheDOMSomehow(data);
thumbnail = document.getElementById(`movie-poster-${movieId}`);
if (thumbnail) {
thumbnail.scrollIntoViewIfNeeded();
thumbnail.style.viewTransitionName = 'movie-poster';
}
});
await transition.finished;
if (thumbnail) {
thumbnail.style.viewTransitionName = '';
}
},
});
}
function handleMovieToPersonTransition(navigateEvent, movieId, personId) {
// TODO: https://developer.chrome.com/docs/web-platform/view-transitions/#not-a-polyfill
// ...has example of `back-transition` class applied to document
const isBack = isBackNavigation(navigateEvent);
navigateEvent.intercept({
async handler() {
const response = await fetch('/fragments/PersonDetails/' + personId);
const data = await response.text();
if (!document.startViewTransition) {
updateTheDOMSomehow(data);
return;
}
let personThumbnail;
let moviePoster;
let movieThumbnail;
if (!isBack) {
// We're transitioning the person photo; we need to remove the transition of the poster
// so that it doesn't stay on the page while transitioning
moviePoster = document.getElementById(`movie-poster`);
if (moviePoster) {
moviePoster.classList.remove('movie-poster');
}
personThumbnail = document.getElementById(`person-photo-${personId}`);
if (personThumbnail) {
personThumbnail.style.viewTransitionName = 'person-photo';
}
}
const transition = document.startViewTransition(() => {
updateTheDOMSomehow(data);
if (personThumbnail) {
personThumbnail.style.viewTransitionName = '';
}
if (isBack) {
// If we're coming back to the person page, we're transitioning
// into the movie poster thumbnail, so we need to add the tag to it
movieThumbnail = document.getElementById(`movie-poster-${movieId}`);
if (movieThumbnail) {
movieThumbnail.scrollIntoViewIfNeeded();
movieThumbnail.style.viewTransitionName = 'movie-poster';
}
}
document.getElementById('container').scrollTop = 0;
});
await transition.finished;
if (movieThumbnail) {
movieThumbnail.style.viewTransitionName = '';
}
},
});
}
function handlePersonToMovieTransition(navigateEvent, personId, movieId) {
const isBack = isBackNavigation(navigateEvent);
navigateEvent.intercept({
scroll: 'manual',
async handler() {
const fragmentUrl = useTvFragment(navigateEvent)
? '/fragments/TvDetails'
: '/fragments/MovieDetails';
const response = await fetch(`${fragmentUrl}/${movieId}`);
const data = await response.text();
if (!document.startViewTransition) {
updateTheDOMSomehow(data);
return;
}
let thumbnail;
let moviePoster;
let movieThumbnail;
if (!isBack) {
movieThumbnail = document.getElementById(`movie-poster-${movieId}`);
if (movieThumbnail) {
movieThumbnail.style.viewTransitionName = 'movie-poster';
}
}
const transition = document.startViewTransition(() => {
updateTheDOMSomehow(data);
if (isBack) {
moviePoster = document.getElementById(`movie-poster`);
if (moviePoster) {
moviePoster.classList.remove('movie-poster');
}
if (personId) {
thumbnail = document.getElementById(`person-photo-${personId}`);
if (thumbnail) {
thumbnail.scrollIntoViewIfNeeded();
thumbnail.style.viewTransitionName = 'person-photo';
}
}
} else {
document.getElementById('container').scrollTop = 0;
if (movieThumbnail) {
movieThumbnail.style.viewTransitionName = '';
}
}
});
await transition.finished;
if (thumbnail) {
thumbnail.style.viewTransitionName = '';
}
if (moviePoster) {
moviePoster.classList.add('movie-poster');
}
},
});
}

View file

@ -0,0 +1,76 @@
export function getNavigationType(fromPath, toPath) {
if (fromPath.startsWith('/movies') && toPath === '/') {
return 'movie-to-home';
}
if (fromPath === '/tv' && toPath.startsWith('/tv/')) {
return 'tv-to-show';
}
if (fromPath === '/' && toPath.startsWith('/movies')) {
return 'home-to-movie';
}
if (fromPath.startsWith('/tv/') && toPath === '/tv') {
return 'show-to-tv';
}
if (
(fromPath.startsWith('/movies') || fromPath.startsWith('/tv')) &&
toPath.startsWith('/people')
) {
return 'movie-to-person';
}
if (
fromPath.startsWith('/people') &&
(toPath.startsWith('/movies') || toPath.startsWith('/tv/'))
) {
return 'person-to-movie';
}
return 'other';
}
export function isBackNavigation(navigateEvent) {
if (navigateEvent.navigationType === 'push' || navigateEvent.navigationType === 'replace') {
return false;
}
if (
navigateEvent.destination.index !== -1 &&
navigateEvent.destination.index < navigation.currentEntry.index
) {
return true;
}
return false;
}
export function shouldNotIntercept(navigationEvent) {
return (
navigationEvent.canIntercept === false ||
// If this is just a hashChange,
// just let the browser handle scrolling to the content.
navigationEvent.hashChange ||
// If this is a download,
// let the browser perform the download.
navigationEvent.downloadRequest ||
// If this is a form submission,
// let that go to the server.
navigationEvent.formData
);
}
export function useTvFragment(navigateEvent) {
const toUrl = new URL(navigateEvent.destination.url);
const toPath = toUrl.pathname;
return toPath.startsWith('/tv');
}
export function getPathId(path) {
return path.split('/')[2];
}
export function updateTheDOMSomehow(data) {
document.getElementById('content').innerHTML = data;
}

View file

@ -0,0 +1,63 @@
@keyframes fade-in {
from {
opacity: 0;
}
}
@keyframes fade-out {
to {
opacity: 0;
}
}
@keyframes slide-from-right {
from {
transform: translateX(30px);
}
}
@keyframes slide-to-left {
to {
transform: translateX(-30px);
}
}
::view-transition-old(root) {
animation:
90ms cubic-bezier(0.4, 0, 1, 1) both fade-out,
300ms cubic-bezier(0.4, 0, 0.2, 1) both slide-to-left;
}
::view-transition-new(root) {
animation:
210ms cubic-bezier(0, 0, 0.2, 1) 90ms both fade-in,
300ms cubic-bezier(0.4, 0, 0.2, 1) both slide-from-right;
}
::view-transition-old(movie-poster),
::view-transition-new(movie-poster) {
animation: none;
mix-blend-mode: normal;
}
::view-transition-image-pair(movie-poster) {
isolation: none;
}
.nav {
view-transition-name: main-header;
contain: paint;
}
.movie-poster {
contain: paint;
}
.person-photo {
view-transition-name: person-photo;
contain: paint;
}
.thumbnail {
contain: paint;
}

View file

@ -0,0 +1,12 @@
/** @type {import('tailwindcss').Config} */
module.exports = {
content: ['./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}'],
theme: {
extend: {
width: {
96: '24rem',
},
},
},
plugins: [],
};

View file

@ -0,0 +1,6 @@
{
"extends": "astro/tsconfigs/base",
"compilerOptions": {
"resolveJsonModule": true
}
}

View file

@ -11,7 +11,7 @@
"astro": "astro"
},
"dependencies": {
"@astrojs/markdoc": "^0.5.0",
"astro": "^3.1.4"
"@astrojs/markdoc": "^0.5.2",
"astro": "^3.2.4"
}
}

View file

@ -11,8 +11,8 @@
"astro": "astro"
},
"dependencies": {
"@astrojs/markdown-remark": "^3.2.0",
"astro": "^3.1.4",
"@astrojs/markdown-remark": "^3.2.1",
"astro": "^3.2.4",
"hast-util-select": "^5.0.5",
"rehype-autolink-headings": "^6.1.1",
"rehype-slug": "^5.1.0",

View file

@ -11,6 +11,6 @@
"astro": "astro"
},
"dependencies": {
"astro": "^3.1.4"
"astro": "^3.2.4"
}
}

View file

@ -11,9 +11,9 @@
"astro": "astro"
},
"dependencies": {
"@astrojs/mdx": "^1.1.0",
"@astrojs/preact": "^3.0.0",
"astro": "^3.1.4",
"@astrojs/mdx": "^1.1.1",
"@astrojs/preact": "^3.0.1",
"astro": "^3.2.4",
"preact": "^10.17.1"
}
}

View file

@ -11,9 +11,9 @@
"astro": "astro"
},
"dependencies": {
"@astrojs/preact": "^3.0.0",
"@astrojs/preact": "^3.0.1",
"@nanostores/preact": "^0.5.0",
"astro": "^3.1.4",
"astro": "^3.2.4",
"nanostores": "^0.9.3",
"preact": "^10.17.1"
}

View file

@ -11,10 +11,10 @@
"astro": "astro"
},
"dependencies": {
"@astrojs/mdx": "^1.1.0",
"@astrojs/tailwind": "^5.0.0",
"@astrojs/mdx": "^1.1.1",
"@astrojs/tailwind": "^5.0.2",
"@types/canvas-confetti": "^1.6.0",
"astro": "^3.1.4",
"astro": "^3.2.4",
"autoprefixer": "^10.4.15",
"canvas-confetti": "^1.6.0",
"postcss": "^8.4.28",

View file

@ -11,7 +11,7 @@
"astro": "astro"
},
"dependencies": {
"astro": "^3.1.4",
"astro": "^3.2.4",
"vite-plugin-pwa": "0.16.4",
"workbox-window": "^7.0.0"
}

View file

@ -12,7 +12,7 @@
"test": "vitest"
},
"dependencies": {
"astro": "^3.1.4",
"astro": "^3.2.4",
"vitest": "^0.34.2"
}
}

View file

@ -1,5 +1,137 @@
# astro
## 3.2.4
### Patch Changes
- [#8638](https://github.com/withastro/astro/pull/8638) [`160d1cd75`](https://github.com/withastro/astro/commit/160d1cd755e70af1d8ec294d01dd2cb32d60db50) Thanks [@florian-lefebvre](https://github.com/florian-lefebvre)! - The `@astrojs/tailwind` integration now creates a `tailwind.config.mjs` file by default
- [#8767](https://github.com/withastro/astro/pull/8767) [`30de32436`](https://github.com/withastro/astro/commit/30de324361bc261956eb9fc08fe60a82ff602a9b) Thanks [@martrapp](https://github.com/martrapp)! - Revert fix #8472
[#8472](https://github.com/withastro/astro/pull/8472) caused some style files from previous pages to not be cleanly deleted on view transitions. For a discussion of a future fix for the original issue [#8144](https://github.com/withastro/astro/issues/8114) see [#8745](https://github.com/withastro/astro/pull/8745).
- [#8741](https://github.com/withastro/astro/pull/8741) [`c4a7ec425`](https://github.com/withastro/astro/commit/c4a7ec4255e7acb9555cb8bb74ea13c5fbb2ac17) Thanks [@lilnasy](https://github.com/lilnasy)! - Fixed an issue on Windows where lowercase drive letters in current working directory led to missing scripts and styles.
- [#8772](https://github.com/withastro/astro/pull/8772) [`c24f70d91`](https://github.com/withastro/astro/commit/c24f70d91601dd3a6b5a84f04d61824e775e9b44) Thanks [@martrapp](https://github.com/martrapp)! - Fix flickering during view transitions
- [#8754](https://github.com/withastro/astro/pull/8754) [`93b092266`](https://github.com/withastro/astro/commit/93b092266febfad16a48575f8eee12d5910bf071) Thanks [@bluwy](https://github.com/bluwy)! - Make CSS chunk names less confusing
- [#8776](https://github.com/withastro/astro/pull/8776) [`29cdfa024`](https://github.com/withastro/astro/commit/29cdfa024886dd581cb207586f7dfec6966bdd4e) Thanks [@martrapp](https://github.com/martrapp)! - Fix transition attributes on islands
- [#8773](https://github.com/withastro/astro/pull/8773) [`eaed844ea`](https://github.com/withastro/astro/commit/eaed844ea8f2f52e0c9caa40bb3ec7377e10595f) Thanks [@sumimakito](https://github.com/sumimakito)! - Fix an issue where HTML attributes do not render if getHTMLAttributes in an image service returns a Promise
## 3.2.3
### Patch Changes
- [#8737](https://github.com/withastro/astro/pull/8737) [`6f60da805`](https://github.com/withastro/astro/commit/6f60da805e0014bc50dd07bef972e91c73560c3c) Thanks [@ematipico](https://github.com/ematipico)! - Add provenance statement when publishing the library from CI
- [#8747](https://github.com/withastro/astro/pull/8747) [`d78806dfe`](https://github.com/withastro/astro/commit/d78806dfe0301ea7ffe6c7c1f783bd415ac7cda9) Thanks [@natemoo-re](https://github.com/natemoo-re)! - Improve error message when user attempts to render a dynamic component reference
- [#8736](https://github.com/withastro/astro/pull/8736) [`d1c75fe15`](https://github.com/withastro/astro/commit/d1c75fe158839699c59728cf3a83888e8c72a459) Thanks [@bluwy](https://github.com/bluwy)! - Fix `tsconfig.json` update causing the server to crash
- [#8743](https://github.com/withastro/astro/pull/8743) [`aa265d730`](https://github.com/withastro/astro/commit/aa265d73024422967c1b1c68ad268c419c6c798f) Thanks [@bluwy](https://github.com/bluwy)! - Remove unused CSS output files when inlined
- [#8700](https://github.com/withastro/astro/pull/8700) [`78adbc443`](https://github.com/withastro/astro/commit/78adbc4433208458291e36713909762e148e1e5d) Thanks [@jacobthesheep](https://github.com/jacobthesheep)! - Update link for Netlify SSR
- [#8729](https://github.com/withastro/astro/pull/8729) [`21e0757ea`](https://github.com/withastro/astro/commit/21e0757ea22a57d344c934045ca19db93b684436) Thanks [@lilnasy](https://github.com/lilnasy)! - Node-based adapters now create less server-side javascript
- [#8730](https://github.com/withastro/astro/pull/8730) [`357270f2a`](https://github.com/withastro/astro/commit/357270f2a3d0bf2aa634ba7e52e9d17618eff4a7) Thanks [@natemoo-re](https://github.com/natemoo-re)! - Improve `astro info` copy to clipboard compatability
- Updated dependencies [[`21f482657`](https://github.com/withastro/astro/commit/21f4826576c2c812a1604e18717799da3470decd), [`6f60da805`](https://github.com/withastro/astro/commit/6f60da805e0014bc50dd07bef972e91c73560c3c), [`21e0757ea`](https://github.com/withastro/astro/commit/21e0757ea22a57d344c934045ca19db93b684436)]:
- @astrojs/markdown-remark@3.2.1
- @astrojs/internal-helpers@0.2.1
- @astrojs/telemetry@3.0.3
## 3.2.2
### Patch Changes
- [#8724](https://github.com/withastro/astro/pull/8724) [`455af3235`](https://github.com/withastro/astro/commit/455af3235b3268852e6988accecc796f03f6d16e) Thanks [@bluwy](https://github.com/bluwy)! - Fix CSS styles on Windows
- [#8710](https://github.com/withastro/astro/pull/8710) [`4c2bec681`](https://github.com/withastro/astro/commit/4c2bec681b0752e7215b8a32bd2d44bf477adac1) Thanks [@matthewp](https://github.com/matthewp)! - Fixes View transition styles being missing when component used multiple times
## 3.2.1
### Patch Changes
- [#8680](https://github.com/withastro/astro/pull/8680) [`31c59ad8b`](https://github.com/withastro/astro/commit/31c59ad8b6a72f95c98a306ecf92d198c03110b4) Thanks [@bluwy](https://github.com/bluwy)! - Fix hydration on slow connection
- [#8698](https://github.com/withastro/astro/pull/8698) [`47ea310f0`](https://github.com/withastro/astro/commit/47ea310f01d06ed1562c790bec348718a2fa8277) Thanks [@Princesseuh](https://github.com/Princesseuh)! - Use a Node-specific image endpoint to resolve images in dev and Node SSR. This should fix many issues related to getting 404 from the \_image endpoint under certain configurations
- [#8706](https://github.com/withastro/astro/pull/8706) [`345808170`](https://github.com/withastro/astro/commit/345808170fce783ddd3c9a4035a91fa64dcc5f46) Thanks [@bluwy](https://github.com/bluwy)! - Fix duplicated Astro and Vite injected styles
## 3.2.0
### Minor Changes
- [#8696](https://github.com/withastro/astro/pull/8696) [`2167ffd72`](https://github.com/withastro/astro/commit/2167ffd72f58904f449ffc6e53581a2d8faf7317) Thanks [@matthewp](https://github.com/matthewp)! - Support adding integrations dynamically
Astro integrations can now themselves dynamically add and configure additional integrations during set-up. This makes it possible for integration authors to bundle integrations more intelligently for their users.
In the following example, a custom integration checks whether `@astrojs/sitemap` is already configured. If not, the integration adds Astros sitemap integration, passing any desired configuration options:
```ts
import sitemap from '@astrojs/sitemap';
import type { AstroIntegration } from 'astro';
const MyIntegration = (): AstroIntegration => {
return {
name: 'my-integration',
'astro:config:setup': ({ config, updateConfig }) => {
// Look for sitemap in user-configured integrations.
const userSitemap = config.integrations.find(
({ name }) => name === '@astrojs/sitemap'
);
if (!userSitemap) {
// If sitemap wasnt found, add it.
updateConfig({
integrations: [sitemap({ /* opts */ }],
});
}
},
};
};
```
- [#8696](https://github.com/withastro/astro/pull/8696) [`2167ffd72`](https://github.com/withastro/astro/commit/2167ffd72f58904f449ffc6e53581a2d8faf7317) Thanks [@matthewp](https://github.com/matthewp)! - View transitions can now be triggered from JavaScript!
Import the client-side router from "astro:transitions/client" and enjoy your new remote control for navigation:
```js
import { navigate } from 'astro:transitions/client';
// Navigate to the selected option automatically.
document.querySelector('select').onchange = (ev) => {
let href = ev.target.value;
navigate(href);
};
```
- [#8696](https://github.com/withastro/astro/pull/8696) [`2167ffd72`](https://github.com/withastro/astro/commit/2167ffd72f58904f449ffc6e53581a2d8faf7317) Thanks [@matthewp](https://github.com/matthewp)! - Route Announcer in `<ViewTransitions />`
The View Transitions router now does route announcement. When transitioning between pages with a traditional MPA approach, assistive technologies will announce the page title when the page finishes loading. This does not automatically happen during client-side routing, so visitors relying on these technologies to announce routes are not aware when a page has changed.
The view transitions route announcer runs after the `astro:page-load` event, looking for the page `<title>` to announce. If one cannot be found, the announcer falls back to the first `<h1>` it finds, or otherwise announces the pathname. We recommend you always include a `<title>` in each page for accessibility.
See the [View Transitions docs](https://docs.astro.build/en/guides/view-transitions/) for more on how accessibility is handled.
### Patch Changes
- [#8647](https://github.com/withastro/astro/pull/8647) [`408b50c5e`](https://github.com/withastro/astro/commit/408b50c5ea5aba66252424f54788557274a58571) Thanks [@lilnasy](https://github.com/lilnasy)! - Fixed an issue where configured redirects with dynamic routes did not work in dev mode.
- [#8696](https://github.com/withastro/astro/pull/8696) [`2167ffd72`](https://github.com/withastro/astro/commit/2167ffd72f58904f449ffc6e53581a2d8faf7317) Thanks [@matthewp](https://github.com/matthewp)! - Fix logLevel passed to Vite build
- [#8696](https://github.com/withastro/astro/pull/8696) [`2167ffd72`](https://github.com/withastro/astro/commit/2167ffd72f58904f449ffc6e53581a2d8faf7317) Thanks [@matthewp](https://github.com/matthewp)! - Fix NoImageMetadata image path error message
- [#8670](https://github.com/withastro/astro/pull/8670) [`e797b6816`](https://github.com/withastro/astro/commit/e797b6816072f63f38d9a91dd2a66765c558d46c) Thanks [@MichailiK](https://github.com/MichailiK)! - Fix asset optimization failing when outDir is outside the project directory
- [#8684](https://github.com/withastro/astro/pull/8684) [`824dd4670`](https://github.com/withastro/astro/commit/824dd4670a145c47337eff84a5ae412bf7443117) Thanks [@matthewp](https://github.com/matthewp)! - Support content collections with % in filename
- [#8648](https://github.com/withastro/astro/pull/8648) [`cfd895d87`](https://github.com/withastro/astro/commit/cfd895d877fdb7fc69e745665a374fc32cb3ef7d) Thanks [@lilnasy](https://github.com/lilnasy)! - Fixed an issue where a response with status code 404 led to an endless loop of implicit rerouting in dev mode.
## 3.1.4
### Patch Changes

View file

@ -3,7 +3,6 @@
// ISOMORPHIC FILE: NO TOP-LEVEL IMPORT/REQUIRE() ALLOWED
// This file has to run as both ESM and CJS on older Node.js versions
// Needed for Stackblitz: https://github.com/stackblitz/webcontainer-core/issues/281
const CI_INSTRUCTIONS = {
NETLIFY: 'https://docs.netlify.com/configure-builds/manage-dependencies/#node-js-and-javascript',
@ -16,15 +15,11 @@ const CI_INSTRUCTIONS = {
const engines = '>=18.14.1';
const skipSemverCheckIfAbove = 19;
// HACK (2023-08-18) Stackblitz does not support Node 18 yet, so we'll fake Node 16 support for some time until it's supported
// TODO: Remove when Node 18 is supported on Stackblitz
const isStackblitz = process.env.SHELL === '/bin/jsh' && process.versions.webcontainer != null;
/** `astro *` */
async function main() {
const version = process.versions.node;
// Fast-path for higher Node.js versions
if (!isStackblitz && (parseInt(version) || 0) <= skipSemverCheckIfAbove) {
if ((parseInt(version) || 0) <= skipSemverCheckIfAbove) {
try {
const semver = await import('semver');
if (!semver.satisfies(version, engines)) {
@ -37,6 +32,13 @@ async function main() {
}
}
// windows drive letters can sometimes be lowercase, which vite cannot process
if (process.platform === 'win32') {
const cwd = process.cwd();
const correctedCwd = cwd.slice(0, 1).toUpperCase() + cwd.slice(1);
if (correctedCwd !== cwd) process.chdir(correctedCwd);
}
return import('./dist/cli/index.js')
.then(({ cli }) => cli(process.argv))
.catch((error) => {

View file

@ -120,6 +120,13 @@ declare module 'astro:transitions' {
export const ViewTransitions: ViewTransitionsModule['default'];
}
declare module 'astro:transitions/client' {
type TransitionRouterModule = typeof import('./dist/transitions/router.js');
export const supportsViewTransitions: TransitionRouterModule['supportsViewTransitions'];
export const transitionEnabledOnThisPage: TransitionRouterModule['transitionEnabledOnThisPage'];
export const navigate: TransitionRouterModule['navigate'];
}
declare module 'astro:middleware' {
export * from 'astro/middleware/namespace';
}

View file

@ -11,91 +11,12 @@ const { fallback = 'animate' } = Astro.props as Props;
<meta name="astro-view-transitions-enabled" content="true" />
<meta name="astro-view-transitions-fallback" content={fallback} />
<script>
type Fallback = 'none' | 'animate' | 'swap';
type Direction = 'forward' | 'back';
type State = {
index: number;
scrollX: number;
scrollY: number;
intraPage?: boolean;
};
type Events = 'astro:page-load' | 'astro:after-swap';
// only update history entries that are managed by us
// leave other entries alone and do not accidently add state.
const persistState = (state: State) => history.state && history.replaceState(state, '');
// @ts-expect-error: startViewTransition might exist
const supportsViewTransitions = !!document.startViewTransition;
const transitionEnabledOnThisPage = () =>
!!document.querySelector('[name="astro-view-transitions-enabled"]');
const triggerEvent = (name: Events) => document.dispatchEvent(new Event(name));
const onPageLoad = () => triggerEvent('astro:page-load');
const PERSIST_ATTR = 'data-astro-transition-persist';
const parser = new DOMParser();
// explained at its usage
let noopEl: HTMLDivElement;
if (import.meta.env.DEV) {
noopEl = document.createElement('div');
}
// The History API does not tell you if navigation is forward or back, so
// you can figure it using an index. On pushState the index is incremented so you
// can use that to determine popstate if going forward or back.
let currentHistoryIndex = 0;
if (history.state) {
// we reloaded a page with history state
// (e.g. history navigation from non-transition page or browser reload)
currentHistoryIndex = history.state.index;
scrollTo({ left: history.state.scrollX, top: history.state.scrollY });
} else if (transitionEnabledOnThisPage()) {
history.replaceState({ index: currentHistoryIndex, scrollX, scrollY, intraPage: false }, '');
}
const throttle = (cb: (...args: any[]) => any, delay: number) => {
let wait = false;
// During the waiting time additional events are lost.
// So repeat the callback at the end if we have swallowed events.
let onceMore = false;
return (...args: any[]) => {
if (wait) {
onceMore = true;
return;
}
cb(...args);
wait = true;
setTimeout(() => {
if (onceMore) {
onceMore = false;
cb(...args);
}
wait = false;
}, delay);
};
};
// returns the contents of the page or null if the router can't deal with it.
async function fetchHTML(
href: string
): Promise<null | { html: string; redirected?: string; mediaType: DOMParserSupportedType }> {
try {
const res = await fetch(href);
// drop potential charset (+ other name/value pairs) as parser needs the mediaType
const mediaType = res.headers.get('content-type')?.replace(/;.*$/, '');
// the DOMParser can handle two types of HTML
if (mediaType !== 'text/html' && mediaType !== 'application/xhtml+xml') {
// everything else (e.g. audio/mp3) will be handled by the browser but not by us
return null;
}
const html = await res.text();
return {
html,
redirected: res.redirected ? res.url : undefined,
mediaType,
};
} catch (err) {
// can't fetch, let someone else deal with it.
return null;
}
}
import {
supportsViewTransitions,
transitionEnabledOnThisPage,
navigate,
} from 'astro:transitions/client';
export type Fallback = 'none' | 'animate' | 'swap';
function getFallback(): Fallback {
const el = document.querySelector('[name="astro-view-transitions-fallback"]');
@ -105,263 +26,6 @@ const { fallback = 'animate' } = Astro.props as Props;
return 'animate';
}
function markScriptsExec() {
for (const script of document.scripts) {
script.dataset.astroExec = '';
}
}
function runScripts() {
let wait = Promise.resolve();
for (const script of Array.from(document.scripts)) {
if (script.dataset.astroExec === '') continue;
const newScript = document.createElement('script');
newScript.innerHTML = script.innerHTML;
for (const attr of script.attributes) {
if (attr.name === 'src') {
const p = new Promise((r) => {
newScript.onload = r;
});
wait = wait.then(() => p as any);
}
newScript.setAttribute(attr.name, attr.value);
}
newScript.dataset.astroExec = '';
script.replaceWith(newScript);
}
return wait;
}
function isInfinite(animation: Animation) {
const effect = animation.effect;
if (!effect || !(effect instanceof KeyframeEffect) || !effect.target) return false;
const style = window.getComputedStyle(effect.target, effect.pseudoElement);
return style.animationIterationCount === 'infinite';
}
const updateHistoryAndScrollPosition = (toLocation) => {
if (toLocation.href !== location.href) {
history.pushState(
{ index: ++currentHistoryIndex, scrollX: 0, scrollY: 0 },
'',
toLocation.href
);
// now we are on the new page for non-history navigations!
// (with history navigation page change happens before popstate is fired)
}
// freshly loaded pages start from the top
scrollTo({ left: 0, top: 0, behavior: 'instant' });
if (toLocation.hash) {
// because we are already on the target page ...
// ... what comes next is a intra-page navigation
// that won't reload the page but instead scroll to the fragment
location.href = toLocation.href;
}
};
// replace head and body of the windows document with contents from newDocument
// if !popstate, update the history entry and scroll position according to toLocation
// if popState is given, this holds the scroll position for history navigation
// if fallback === "animate" then simulate view transitions
async function updateDOM(
newDocument: Document,
toLocation: URL,
popState?: State,
fallback?: Fallback
) {
// Check for a head element that should persist and returns it,
// either because it has the data attribute or is a link el.
const persistedHeadElement = (el: HTMLElement): Element | null => {
const id = el.getAttribute(PERSIST_ATTR);
const newEl = id && newDocument.head.querySelector(`[${PERSIST_ATTR}="${id}"]`);
if (newEl) {
return newEl;
}
if (el.matches('link[rel=stylesheet]')) {
const href = el.getAttribute('href');
return newDocument.head.querySelector(`link[rel=stylesheet][href="${href}"]`);
}
// What follows is a fix for an issue (#8472) with missing client:only styles after transition.
// That problem exists only in dev mode where styles are injected into the page by Vite.
// Returning a noop element ensures that the styles are not removed from the old document.
// Guarding the code below with the dev mode check
// allows tree shaking to remove this code in production.
if (import.meta.env.DEV) {
if (el.tagName === 'STYLE' && el.dataset.viteDevId) {
const devId = el.dataset.viteDevId;
// If this same style tag exists, remove it from the new page
return (
newDocument.querySelector(`style[data-astro-dev-id="${devId}"]`) ||
// Otherwise, keep it anyways. This is client:only styles.
noopEl
);
}
}
return null;
};
const swap = () => {
// swap attributes of the html element
// - delete all attributes from the current document
// - insert all attributes from doc
// - reinsert all original attributes that are named 'data-astro-*'
const html = document.documentElement;
const astro = [...html.attributes].filter(
({ name }) => (html.removeAttribute(name), name.startsWith('data-astro-'))
);
[...newDocument.documentElement.attributes, ...astro].forEach(({ name, value }) =>
html.setAttribute(name, value)
);
// Replace scripts in both the head and body.
for (const s1 of document.scripts) {
for (const s2 of newDocument.scripts) {
if (
// Inline
(!s1.src && s1.textContent === s2.textContent) ||
// External
(s1.src && s1.type === s2.type && s1.src === s2.src)
) {
// the old script is in the new document: we mark it as executed to prevent re-execution
s2.dataset.astroExec = '';
break;
}
}
}
// Swap head
for (const el of Array.from(document.head.children)) {
const newEl = persistedHeadElement(el as HTMLElement);
// If the element exists in the document already, remove it
// from the new document and leave the current node alone
if (newEl) {
newEl.remove();
} else {
// Otherwise remove the element in the head. It doesn't exist in the new page.
el.remove();
}
}
// Everything left in the new head is new, append it all.
document.head.append(...newDocument.head.children);
// Persist elements in the existing body
const oldBody = document.body;
// this will reset scroll Position
document.body.replaceWith(newDocument.body);
for (const el of oldBody.querySelectorAll(`[${PERSIST_ATTR}]`)) {
const id = el.getAttribute(PERSIST_ATTR);
const newEl = document.querySelector(`[${PERSIST_ATTR}="${id}"]`);
if (newEl) {
// The element exists in the new page, replace it with the element
// from the old page so that state is preserved.
newEl.replaceWith(el);
}
}
if (popState) {
scrollTo(popState.scrollX, popState.scrollY); // usings 'auto' scrollBehavior
} else {
updateHistoryAndScrollPosition(toLocation);
}
triggerEvent('astro:after-swap');
};
// Wait on links to finish, to prevent FOUC
const links: Promise<any>[] = [];
for (const el of newDocument.querySelectorAll('head link[rel=stylesheet]')) {
// Do not preload links that are already on the page.
if (
!document.querySelector(
`[${PERSIST_ATTR}="${el.getAttribute(PERSIST_ATTR)}"], link[rel=stylesheet]`
)
) {
const c = document.createElement('link');
c.setAttribute('rel', 'preload');
c.setAttribute('as', 'style');
c.setAttribute('href', el.getAttribute('href')!);
links.push(
new Promise<any>((resolve) => {
['load', 'error'].forEach((evName) => c.addEventListener(evName, resolve));
document.head.append(c);
})
);
}
}
links.length && (await Promise.all(links));
if (fallback === 'animate') {
// Trigger the animations
const currentAnimations = document.getAnimations();
document.documentElement.dataset.astroTransitionFallback = 'old';
const newAnimations = document
.getAnimations()
.filter((a) => !currentAnimations.includes(a) && !isInfinite(a));
const finished = Promise.all(newAnimations.map((a) => a.finished));
const fallbackSwap = () => {
swap();
document.documentElement.dataset.astroTransitionFallback = 'new';
};
await finished;
fallbackSwap();
} else {
swap();
}
}
async function transition(direction: Direction, toLocation: URL, popState?: State) {
let finished: Promise<void>;
const href = toLocation.href;
const response = await fetchHTML(href);
// If there is a problem fetching the new page, just do an MPA navigation to it.
if (response === null) {
location.href = href;
return;
}
// if there was a redirection, show the final URL in the browser's address bar
if (response.redirected) {
toLocation = new URL(response.redirected);
}
const newDocument = parser.parseFromString(response.html, response.mediaType);
// The next line might look like a hack,
// but it is actually necessary as noscript elements
// and their contents are returned as markup by the parser,
// see https://developer.mozilla.org/en-US/docs/Web/API/DOMParser/parseFromString
newDocument.querySelectorAll('noscript').forEach((el) => el.remove());
if (!newDocument.querySelector('[name="astro-view-transitions-enabled"]')) {
location.href = href;
return;
}
if (!popState) {
// save the current scroll position before we change the DOM and transition to the new page
history.replaceState({ ...history.state, scrollX, scrollY }, '');
}
document.documentElement.dataset.astroTransition = direction;
if (supportsViewTransitions) {
// @ts-expect-error: startViewTransition exist
finished = document.startViewTransition(() =>
updateDOM(newDocument, toLocation, popState)
).finished;
} else {
finished = updateDOM(newDocument, toLocation, popState, getFallback());
}
try {
await finished;
} finally {
// skip this for the moment as it tends to stop fallback animations
// document.documentElement.removeAttribute('data-astro-transition');
await runScripts();
markScriptsExec();
onPageLoad();
}
}
// Prefetching
function maybePrefetch(pathname: string) {
if (document.querySelector(`link[rel=prefetch][href="${pathname}"]`)) return;
@ -406,83 +70,9 @@ const { fallback = 'animate' } = Astro.props as Props;
return;
}
ev.preventDefault();
navigate(link.href);
navigate(link.href, {
history: link.dataset.astroHistory === 'replace' ? 'replace' : 'auto',
});
function navigate(href) {
// not ours
if (!transitionEnabledOnThisPage()) {
location.href = href;
return;
}
const toLocation = new URL(href, location.href);
// We do not have page transitions on navigations to the same page (intra-page navigation)
// but we want to handle prevent reload on navigation to the same page
// Same page means same origin, path and query params (but maybe different hash)
if (
location.origin === toLocation.origin &&
location.pathname === toLocation.pathname &&
location.search === toLocation.search
) {
// mark current position as non transition intra-page scrolling
if (location.href !== toLocation.href) {
history.replaceState({ ...history.state, intraPage: true }, '');
history.pushState(
{ index: ++currentHistoryIndex, scrollX: 0, scrollY: 0 },
'',
toLocation.href
);
}
if (toLocation.hash) {
location.href = toLocation.href;
} else {
scrollTo({ left: 0, top: 0, behavior: 'instant' });
}
} else {
transition('forward', toLocation);
}
}
addEventListener('popstate', (ev) => {
if (!transitionEnabledOnThisPage() && ev.state) {
// The current page doesn't have View Transitions enabled
// but the page we navigate to does (because it set the state).
// Do a full page refresh to reload the client-side router from the new page.
// Scroll restauration will then happen during the reload when the router's code is re-executed
if (history.scrollRestoration) {
history.scrollRestoration = 'manual';
}
location.reload();
return;
}
// History entries without state are created by the browser (e.g. for hash links)
// Our view transition entries always have state.
// Just ignore stateless entries.
// The browser will handle navigation fine without our help
if (ev.state === null) {
if (history.scrollRestoration) {
history.scrollRestoration = 'auto';
}
return;
}
// With the default "auto", the browser will jump to the old scroll position
// before the ViewTransition is complete.
if (history.scrollRestoration) {
history.scrollRestoration = 'manual';
}
const state: State = history.state;
if (state.intraPage) {
// this is non transition intra-page scrolling
scrollTo(state.scrollX, state.scrollY);
} else {
const nextIndex = state.index;
const direction: Direction = nextIndex > currentHistoryIndex ? 'forward' : 'back';
currentHistoryIndex = nextIndex;
transition(direction, new URL(location.href), state);
}
});
['mouseenter', 'touchstart', 'focus'].forEach((evName) => {
@ -503,17 +93,5 @@ const { fallback = 'animate' } = Astro.props as Props;
{ passive: true, capture: true }
);
});
addEventListener('load', onPageLoad);
// There's not a good way to record scroll position before a back button.
// So the way we do it is by listening to scrollend if supported, and if not continuously record the scroll position.
const updateState = () => {
persistState({ ...history.state, scrollX, scrollY });
};
if ('onscrollend' in window) addEventListener('scrollend', updateState);
else addEventListener('scroll', throttle(updateState, 300));
markScriptsExec();
}
</script>

View file

@ -1,36 +0,0 @@
import { expect } from '@playwright/test';
import { testFactory } from './test-utils.js';
const test = testFactory({
root: './fixtures/css/',
});
let devServer;
test.beforeAll(async ({ astro }) => {
devServer = await astro.startDevServer();
});
test.afterAll(async () => {
await devServer.stop();
});
test.describe('CSS Sourcemap HMR', () => {
test('removes Astro-injected CSS once Vite-injected CSS loads', async ({ page, astro }) => {
const html = await astro.fetch('/').then((res) => res.text());
// style[data-astro-dev-id] should exist in initial SSR'd markup
expect(html).toMatch('data-astro-dev-id');
await page.goto(astro.resolveUrl('/'));
// Ensure JS has initialized
await page.waitForTimeout(500);
// style[data-astro-dev-id] should NOT exist once JS runs
expect(await page.locator('style[data-astro-dev-id]').count()).toEqual(0);
// style[data-vite-dev-id] should exist now
expect(await page.locator('style[data-vite-dev-id]').count()).toBeGreaterThan(0);
});
});

View file

@ -29,21 +29,9 @@ test.describe('CSS HMR', () => {
await expect(h).toHaveCSS('color', 'rgb(0, 128, 0)');
});
test('removes Astro-injected CSS once Vite-injected CSS loads', async ({ page, astro }) => {
test('removes Astro-injected CSS once Vite-injected CSS loads', async ({ astro }) => {
const html = await astro.fetch('/').then((res) => res.text());
// style[data-astro-dev-id] should exist in initial SSR'd markup
expect(html).toMatch('data-astro-dev-id');
await page.goto(astro.resolveUrl('/'));
// Ensure JS has initialized
await page.waitForTimeout(500);
// style[data-astro-dev-id] should NOT exist once JS runs
expect(await page.locator('style[data-astro-dev-id]').count()).toEqual(0);
// style[data-vite-dev-id] should exist now
expect(await page.locator('style[data-vite-dev-id]').count()).toBeGreaterThan(0);
// style[data-vite-dev-id] should exist in initial SSR'd markup
expect(html).toMatch('data-vite-dev-id');
});
});

View file

@ -1,7 +0,0 @@
export default {
vite: {
css: {
devSourcemap: true,
}
}
};

View file

@ -1 +0,0 @@
/// <reference types="astro/client" />

View file

@ -1,9 +0,0 @@
<h1>hello world</h1>
<style>
@import "../styles/main.css";
h1 {
color: var(--h1-color);
}
</style>

View file

@ -1,3 +0,0 @@
:root {
--h1-color: red;
}

View file

@ -0,0 +1,3 @@
#one {
background-color: whitesmoke;
}

View file

@ -0,0 +1,3 @@
h1 {
color: blue
}

Some files were not shown because too many files have changed in this diff Show more