astro-loader-ins-medias
v1.0.1
Published
Astro loader for loading Instagram medias.
Maintainers
Readme
astro-loader-ins-medias
This package provides Instagram media loaders for Astro projects using the Instagram API with Instagram Login. It includes:
insMediasLoader: Loads Instagram media at build time.liveInsMediasLoader: Fetches Instagram media at runtime on each request.
Prerequisites
To use this loader, you need to get an access token from Meta. This requires a few steps:
- Instagram Professional Account: Your Instagram account must be a Business or Creator account. You can switch your account type in the Instagram app settings.
- Meta Developer Account: Register as a developer at Meta for Developers.
- Create a Meta App for Instagram: In the App Dashboard, create a Meta app to get the token later. You can skip “Connect a business”.
- Generate Access Token: Go to Instagram > API Setup with Instagram Business Login, click Generate Token next to the target Instagram account, log into Instagram Professional Account, and copy the generated access token (valid for 60 days).
Installation
npm install astro-loader-ins-mediasUsage
To use the Astro loader, ensure Astro version ^4.14.0 || ^5.0.0. For ^4.14.0, enable the experimental content layer in astro.config.ts:
export default defineConfig({
experimental: {
contentLayer: true,
},
})insMediasLoader (Build-time Collection)
In src/content/config.ts (for ^4.14.0) or src/content.config.ts (for ^5.0.0), import and configure the build-time loader to define a new content collection:
import { defineCollection } from "astro:content"
import { insMediasLoader } from "astro-loader-ins-medias"
const insMedias = defineCollection({
loader: insMediasLoader({
fields: 'id,permalink,caption,media_url',
mediaTypes: ['IMAGE', 'VIDEO', 'CAROUSEL_ALBUM'],
since: new Date('2024-01-01'),
until: '2024-12-31',
limit: 10,
apiVersion: 'v23.0',
}),
})
export const collections = { insMedias }Query the content collection like any other Astro content collection to render the loaded Instagram medias:
---
import { getCollection } from "astro:content";
const medias = await getCollection("insMedias");
---
{medias.map((media) => {
const { permalink, media_url, caption } = media.data;
return (
<a href={permalink}>
<img src={media_url} alt={caption} />
<p>{caption}</p>
</a>
);
})}To update the data, trigger a site rebuild (e.g., using a third-party cron job service), as the loader fetches data only at build time.
liveInsMediasLoader (Live Collection, Experimental)
Astro 5.10+ introduces experimental live content collections, which allow data fetching at runtime. To use this feature, enable the experimental liveContentCollections flag as shown below, and use an adapter that supports on-demand rendering.
// astro.config.mjs
export default {
experimental: {
liveContentCollections: true,
},
};In src/live.config.ts, import and configure the live loader to define a new live content collection:
// src/live.config.ts
import { defineLiveCollection } from 'astro:content';
import { liveInsMediasLoader } from 'astro-loader-ins-medias';
const liveInsMedias = defineLiveCollection({
loader: liveInsMediasLoader(),
});
export const collections = { liveInsMedias };Query at runtime using getLiveCollection() or getLiveEntry():
---
export const prerender = false;
import { getLiveCollection, getLiveEntry } from 'astro:content';
// Get medias
const { entries: medias, error } = await getLiveCollection('liveInsMedias',{
fields: 'id,permalink,caption,media_url',
mediaTypes: ['IMAGE', 'VIDEO', 'CAROUSEL_ALBUM'],
since: new Date('2024-01-01'),
until: '2024-12-31',
limit: 10,
apiVersion: 'v23.0',
});
// Get individual media
/* const { entry: media } = await getLiveEntry('liveInsMedias', {
mediaId: '17862623307162462',
}); */
---
{
error ? (
<p>{error.message}</p>
) : (
<div>
{medias?.map((media) => {
const { permalink, media_url, caption } = media.data;
return (
<a href={permalink}>
<img src={media_url} alt={caption} />
<p>{caption}</p>
</a>
);
})}
</div>
)
}Configuration
insMediasLoader Options
| Option (* required) | Type (default) | Description |
| ------------------- | ------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| fields | string (default) | A string that specifies which Instagram media fields to fetch, and optionally additional fields from supported edges. Note:- Default fields have exact types defined in the schema, any extra fields you add will be typed as unknown.- You can provide your own schema, or import and extend InsMediaSchema, to validate the data and generate TypeScript types for your collection.- To fetch edge fields, include them in the format edge{field1,field2}.Ref: Fields reference、edges Edges reference |
| mediaTypes | ('IMAGE' \| 'VIDEO' \| 'CAROUSEL_ALBUM')[](default: ['IMAGE', 'VIDEO', 'CAROUSEL_ALBUM']) | Filter by media type. If not specified, all media types will be loaded. |
| since | Date \| string \| number | Only load medias after this date. It must be a valid Date or a value convertible by new Date(). |
| until | Date \| string \| number | Only load medias before this date. It must be a valid Date or a value convertible by new Date(). |
| limit | number | Maximum number of media items to load. |
| apiVersion | string ("v23.0") | The API version to use for the Instagram API. |
| instagramToken | string | You need to get an access token that ensures the loader can access the Instagram API with Instagram Login. Defaults to the INSTAGRAM_TOKEN environment variable. If configured here, keep confidential and avoid public exposure. See how to create one and configure env vars in an Astro project. Note: Access tokens from the App Dashboard are are valid for 60 days. |
liveInsMediasLoader Options
| Option (* required) | Type (default) | Description |
| ------------------- | ---------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| fields | string (default) | A string that specifies which Instagram media fields to fetch, and optionally additional fields from supported edges. Note:- Default fields have exact types defined in the schema, any extra fields you add will be typed as unknown.- You can provide your own schema, or import and extend InsMediaSchema, to validate the data and generate TypeScript types for your collection.- To fetch edge fields, include them in the format edge{field1,field2}.Ref: Fields reference、edges Edges reference |
| apiVersion | string ("v23.0") | The API version to use for the Instagram API. |
| instagramToken | string | You need to get an access token that ensures the loader can access the Instagram API with Instagram Login. Defaults to the INSTAGRAM_TOKEN environment variable. If configured here, keep confidential and avoid public exposure. See how to create one and configure env vars in an Astro project. Note: Access tokens from the App Dashboard are are valid for 60 days. |
liveInsMediasLoader Collection Filters
| Option (* required) | Type (default) | Description |
| ------------------- | ---------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| fields | string (default) | A string that specifies which Instagram media fields to fetch, and optionally additional fields from supported edges. Note:- Default fields have exact types defined in the schema, any extra fields you add will be typed as unknown.- You can provide your own schema, or import and extend InsMediaSchema, to validate the data and generate TypeScript types for your collection.- To fetch edge fields, include them in the format edge{field1,field2}.Ref: Fields reference、edges Edges reference |
| mediaTypes | ('IMAGE' \| 'VIDEO' \| 'CAROUSEL_ALBUM')[](default: ['IMAGE', 'VIDEO', 'CAROUSEL_ALBUM']) | Filter by media type. If not specified, all media types will be loaded. |
| since | Date \| string \| number | Only load medias after this date. It must be a valid Date or a value convertible by new Date(). |
| until | Date \| string \| number | Only load medias before this date. It must be a valid Date or a value convertible by new Date(). |
| limit | number | Maximum number of media items to load. |
liveInsMediasLoader Entry Filters
| Option (* required) | Type (default) | Description |
| ------------------- | ---------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| mediaId* | number | The ID of the media item. |
| fields | string (default) | A string that specifies which Instagram media fields to fetch, and optionally additional fields from supported edges. Note:- Default fields have exact types defined in the schema, any extra fields you add will be typed as unknown.- You can provide your own schema, or import and extend InsMediaSchema, to validate the data and generate TypeScript types for your collection.- To fetch edge fields, include them in the format edge{field1,field2}.Ref: Fields reference、edges Edges reference |
Schema
The collection entries use the following Zod schema:
const InsMediaSchema = z
.object({
id: z.string(),
caption: z.string(),
comments_count: z.number().int(),
like_count: z.number().int(),
media_product_type: z.enum(['AD', 'FEED', 'STORY', 'REELS']),
media_type: z.enum(['IMAGE', 'VIDEO', 'CAROUSEL_ALBUM']),
media_url: z.string().url(),
permalink: z.string().url(),
timestamp: z.coerce.date(),
children: z.object({
data: z.array(
z
.object({
id: z.string(),
media_type: z.enum(['IMAGE', 'VIDEO', 'CAROUSEL_ALBUM']),
media_url: z.string().url(),
})
.partial()
.required({ id: true })
.passthrough()
),
}),
comments: z.object({
data: z.array(
z
.object({
id: z.string(),
username: z.string(),
text: z.string(),
timestamp: z.coerce.date(),
})
.partial()
.required({ id: true })
.passthrough()
),
}),
})
.partial()
.required({ id: true })
.passthrough()Astro uses these schemas to generate TypeScript interfaces for autocompletion and type safety. When customizing the collection schema, keep it compatible with the loader’s built-in Zod schema to avoid errors.
Live Collections Error Handling
Live loaders may fail due to network, API, or validation errors. Handle these errors in your components. The live loader also returns specific error codes:
INVALID_FILTER: Missing required filter options.COLLECTION_LOAD_ERROR: Failed to load collection.ENTRY_LOAD_ERROR: Failed to load individual entry.INS_API_QUERY_ERROR: Failed to query Instagram API.
Changelog
See CHANGELOG.md for the change history of this loader.
Contribution
If you see any errors or room for improvement, feel free to open an issues or pull request . Thank you in advance for contributing! ❤️
