Skip to content

When writing a content rich site a common requirement is to show when some content was published, when it was last updated and who participated in authoring that content. Instead of tracking this manually for each entry in your content collections, this library allows you to retrieve that information from your Git history.

Git is only necessary during build, so you can deploy your site anywhere. Even on platforms that don’t provide Git, access to binaries or native modules (yes, even on Cloudflare).

How to use

  1. Install @inox-tools/content-utils:

    Terminal window
    npx astro add @inox-tools/content-utils
  2. Import the time getter you want from @it-astro:content/git:

    src/pages/blog/[...slug].astro
    ---
    import {
    getLatestCommitDate,
    getOldestCommitDate,
    getEntryGitInfo,
    } from '@it-astro:content/git';
    ---
  3. Get the time or information about any collection entry using the same signature as Astro’s getEntry:

    src/pages/blog/[...slug].astro
    ---
    import { getOldestCommitDate } from '@it-astro:content/git';
    const { slug } = Astro.params;
    const entry = await getEntry('blog', slug);
    const creationDate = await getOldestCommitDate('blog', slug);
    // OR
    const creationDate = await getOldestCommitDate(entry);
    ---

API

getLatestCommitDate

Returns the commit time of the last commit that changed the selected entry.
If the entry has not been commited yet, this function returns the current time.

getOldestCommitDate

Returns the commit time of the first commit that created the selected entry.
If the entry has not been commited yet, this function returns the current time.

getEntryGitInfo

Returns all the collected Git information related to the selected entry. If the entry has not been commited yet, this function returns undefined.

  • earliest: Commit time of the commit that first created the path of the collection entry, same as returned by [getOldestCommitDate].
  • latest: Commit time of the last commit that modified the path of the collection entry.
  • authors: The authors of the commits that modified the path of the collection entry.
  • coAuthors: The co-authors of the commits that modified the path of the collection entry. This is inferred from the Co-Authored-By commit trailers. Although this is not part of any specification, this is the practiced followed by most Git UIs and Git hosting platforms.

Type definition:

type GitTrackingInfo = {
earliest: Date;
latest: Date;
authors: GitAuthor[];
coAuthors: GitAuthor[];
};
type GitAuthor = {
name: string;
email: string;
};

Hooks

Integrations can hook into the lifecycle of the content collections git times, this allows you to:

  • Ignore some collection entries;
  • Override times for entries.

@it/content:git:listed

This hook is called on astro build once the collection entries tracked by Git are listed.

your-integration/index.ts
import { defineIntegration } from 'astro-integration-kit';
import '@inox-tools/content-utils';
export default defineIntegration({
name: 'your-integration',
setup() {
return {
hooks: {
'@it/content:git:listed': ({ trackedFiles, ignoreFiles, logger }) => {
// your code
},
},
};
},
});

trackedFiles

Type: string[]

List of all content collection entry files that are tracked by Git. The values are in

ignoreFiles

Type: (files: string[]) => void

A callback to exclude files from tracking. Values that is not on trackedFiles are ignored.

logger

Type: AstroIntegrationLogger

A standard AstroIntegrationLogger, configured the same as for the official Astro hooks.

@it/content:git:resolved

This hook is called twice for each tracked content collection entry, once for each git time that is resolved (oldest and latest).

your-integration/index.ts
import { defineIntegration } from 'astro-integration-kit';
import '@inox-tools/content-utils';
export default defineIntegration({
name: 'your-integration',
setup() {
return {
hooks: {
'@it/content:git:resolved': ({ age, file, resolvedDate, overrideDate, logger }) => {
// your code
},
},
};
},
});

age

Type: 'oldest' | 'latest'

Which age of the entry is being resolved, oldest, latest.

file

Type: string

Absolute path to the content collection entry file.

resolvedDate

Type: Date

Date resolved from the Git history.

overrideDate

Type: (newDate: Date) => void

Callback function to override the resolved date.