├── .changeset ├── README.md └── config.json ├── .envrc ├── .eslintrc ├── .github ├── stale.yml └── workflows │ └── ci.yml ├── .gitignore ├── .gitmodules ├── .gitpod.yml ├── .infra ├── .gitignore ├── docker-compose.yml ├── grafana-datasources.yml ├── grafana.ini ├── otel-collector.yml ├── prometheus.yml └── tempo.yml ├── .prettierignore ├── .vscode ├── common-imports.code-snippets ├── extensions.json ├── operators.code-snippets ├── settings.json └── tasks.json ├── .yarn ├── plugins │ └── @yarnpkg │ │ ├── plugin-interactive-tools.cjs │ │ ├── plugin-typescript.cjs │ │ ├── plugin-version.cjs │ │ └── plugin-workspace-tools.cjs ├── releases │ └── yarn-3.2.3.cjs └── sdks │ ├── integrations.yml │ └── typescript │ ├── bin │ ├── tsc │ └── tsserver │ ├── lib │ ├── tsc.js │ ├── tsserver.js │ └── typescript.js │ └── package.json ├── .yarnrc.yml ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── examples ├── archive │ ├── playground-azimuth-colocated │ │ ├── content │ │ │ ├── data │ │ │ │ ├── authors │ │ │ │ │ ├── jane-doe.yaml │ │ │ │ │ └── john-doe.yaml │ │ │ │ └── config.json │ │ │ └── pages │ │ │ │ ├── about.md │ │ │ │ ├── blog.md │ │ │ │ ├── blog │ │ │ │ ├── azimuth-improvements.md │ │ │ │ ├── customer-loyalty.md │ │ │ │ ├── customer-service-skills-that-every-employee-needs.md │ │ │ │ ├── design-azimuth.md │ │ │ │ ├── design-team-collaborates.md │ │ │ │ ├── sales-as-service.md │ │ │ │ ├── set-big-goals.md │ │ │ │ ├── user-journey-mapping.md │ │ │ │ └── working-from-home.md │ │ │ │ ├── contact.md │ │ │ │ ├── features.md │ │ │ │ ├── index.md │ │ │ │ ├── pricing.md │ │ │ │ ├── privacy-policy.md │ │ │ │ ├── signup.md │ │ │ │ ├── style-guide.md │ │ │ │ └── terms-of-service.md │ │ ├── contentlayer-stackbit-yaml-generator.js │ │ ├── contentlayer.config.ts │ │ ├── next-env.d.ts │ │ ├── next.config.js │ │ ├── package.json │ │ ├── public │ │ │ ├── images │ │ │ │ ├── 1.jpg │ │ │ │ ├── 10.jpg │ │ │ │ ├── 10_thumb.jpg │ │ │ │ ├── 11.jpg │ │ │ │ ├── 11_thumb.jpg │ │ │ │ ├── 12.jpg │ │ │ │ ├── 12_thumb.jpg │ │ │ │ ├── 1_thumb.jpg │ │ │ │ ├── 2.jpg │ │ │ │ ├── 2_thumb.jpg │ │ │ │ ├── 3.jpg │ │ │ │ ├── 3_thumb.jpg │ │ │ │ ├── 4.jpg │ │ │ │ ├── 4_thumb.jpg │ │ │ │ ├── 5.jpg │ │ │ │ ├── 5_thumb.jpg │ │ │ │ ├── 6.jpg │ │ │ │ ├── 6_thumb.jpg │ │ │ │ ├── 7.jpg │ │ │ │ ├── 7_thumb.jpg │ │ │ │ ├── 8.jpg │ │ │ │ ├── 8_thumb.jpg │ │ │ │ ├── 9.jpg │ │ │ │ ├── 9_thumb.jpg │ │ │ │ ├── about.jpg │ │ │ │ ├── author.jpg │ │ │ │ ├── avatar.png │ │ │ │ ├── favicon.png │ │ │ │ ├── feature1.png │ │ │ │ ├── feature2.png │ │ │ │ ├── feature3.png │ │ │ │ ├── hero.png │ │ │ │ ├── intro.jpg │ │ │ │ ├── logo-alt.svg │ │ │ │ ├── logo.svg │ │ │ │ ├── review1.jpg │ │ │ │ ├── review2.jpg │ │ │ │ └── review3.jpg │ │ │ └── js │ │ │ │ ├── init.js │ │ │ │ ├── main.js │ │ │ │ └── plugins.js │ │ ├── src │ │ │ ├── components │ │ │ │ ├── Action.tsx │ │ │ │ ├── ActionLink.tsx │ │ │ │ ├── BlogPostFooter.tsx │ │ │ │ ├── FormField.tsx │ │ │ │ ├── Header.tsx │ │ │ │ ├── Icon.tsx │ │ │ │ ├── Layout.tsx │ │ │ │ ├── footer │ │ │ │ │ ├── Footer.tsx │ │ │ │ │ ├── FooterForm.tsx │ │ │ │ │ ├── FooterNav.tsx │ │ │ │ │ └── FooterText.tsx │ │ │ │ └── landing-sections │ │ │ │ │ ├── CtaButtons.tsx │ │ │ │ │ ├── SectionContact.tsx │ │ │ │ │ ├── SectionContent.tsx │ │ │ │ │ ├── SectionCta.tsx │ │ │ │ │ ├── SectionFaq.tsx │ │ │ │ │ ├── SectionFeatures.tsx │ │ │ │ │ ├── SectionHero.tsx │ │ │ │ │ ├── SectionPosts.tsx │ │ │ │ │ ├── SectionPricing.tsx │ │ │ │ │ ├── SectionReviews.tsx │ │ │ │ │ └── model.ts │ │ │ ├── contentlayer │ │ │ │ ├── documents │ │ │ │ │ ├── Config.ts │ │ │ │ │ └── Person.ts │ │ │ │ ├── index.ts │ │ │ │ └── objects │ │ │ │ │ └── SEO.ts │ │ │ ├── layouts │ │ │ │ ├── BlogLayout.tsx │ │ │ │ ├── LandingLayout.tsx │ │ │ │ ├── PageLayout.tsx │ │ │ │ └── PostLayout.tsx │ │ │ ├── pages │ │ │ │ ├── [[...slug]].tsx │ │ │ │ └── _app.tsx │ │ │ ├── sass │ │ │ │ ├── imports │ │ │ │ │ ├── _banner.scss │ │ │ │ │ ├── _buttons.scss │ │ │ │ │ ├── _footer.scss │ │ │ │ │ ├── _forms.scss │ │ │ │ │ ├── _functions.scss │ │ │ │ │ ├── _general.scss │ │ │ │ │ ├── _header.scss │ │ │ │ │ ├── _helpers.scss │ │ │ │ │ ├── _icons.scss │ │ │ │ │ ├── _menus.scss │ │ │ │ │ ├── _palettes.scss │ │ │ │ │ ├── _posts.scss │ │ │ │ │ ├── _reset.scss │ │ │ │ │ ├── _sections.scss │ │ │ │ │ ├── _structure.scss │ │ │ │ │ ├── _tables.scss │ │ │ │ │ └── _variables.scss │ │ │ │ └── main.scss │ │ │ └── utils │ │ │ │ ├── classNames.tsx │ │ │ │ ├── contentlayer.ts │ │ │ │ ├── htmlToReact.tsx │ │ │ │ ├── index.ts │ │ │ │ ├── link.tsx │ │ │ │ ├── markdownify.tsx │ │ │ │ ├── next.ts │ │ │ │ └── withPrefix.ts │ │ ├── stackbit.yaml │ │ └── tsconfig.json │ ├── playground-azimuth-contentful │ │ ├── contentlayer-stackbit-yaml-generator.js │ │ ├── contentlayer.config.ts │ │ ├── copy-code.sh │ │ ├── next-env.d.ts │ │ ├── next.config.js │ │ ├── package.json │ │ ├── public │ │ │ ├── images │ │ │ │ ├── 1.jpg │ │ │ │ ├── 10.jpg │ │ │ │ ├── 10_thumb.jpg │ │ │ │ ├── 11.jpg │ │ │ │ ├── 11_thumb.jpg │ │ │ │ ├── 12.jpg │ │ │ │ ├── 12_thumb.jpg │ │ │ │ ├── 1_thumb.jpg │ │ │ │ ├── 2.jpg │ │ │ │ ├── 2_thumb.jpg │ │ │ │ ├── 3.jpg │ │ │ │ ├── 3_thumb.jpg │ │ │ │ ├── 4.jpg │ │ │ │ ├── 4_thumb.jpg │ │ │ │ ├── 5.jpg │ │ │ │ ├── 5_thumb.jpg │ │ │ │ ├── 6.jpg │ │ │ │ ├── 6_thumb.jpg │ │ │ │ ├── 7.jpg │ │ │ │ ├── 7_thumb.jpg │ │ │ │ ├── 8.jpg │ │ │ │ ├── 8_thumb.jpg │ │ │ │ ├── 9.jpg │ │ │ │ ├── 9_thumb.jpg │ │ │ │ ├── about.jpg │ │ │ │ ├── author.jpg │ │ │ │ ├── avatar.png │ │ │ │ ├── favicon.png │ │ │ │ ├── feature1.png │ │ │ │ ├── feature2.png │ │ │ │ ├── feature3.png │ │ │ │ ├── hero.png │ │ │ │ ├── intro.jpg │ │ │ │ ├── logo-alt.svg │ │ │ │ ├── logo.svg │ │ │ │ ├── review1.jpg │ │ │ │ ├── review2.jpg │ │ │ │ └── review3.jpg │ │ │ └── js │ │ │ │ ├── init.js │ │ │ │ ├── main.js │ │ │ │ └── plugins.js │ │ ├── src │ │ │ ├── components │ │ │ │ ├── Action.tsx │ │ │ │ ├── ActionLink.tsx │ │ │ │ ├── BlogPostFooter.tsx │ │ │ │ ├── FormField.tsx │ │ │ │ ├── Header.tsx │ │ │ │ ├── Icon.tsx │ │ │ │ ├── Layout.tsx │ │ │ │ ├── footer │ │ │ │ │ ├── Footer.tsx │ │ │ │ │ ├── FooterForm.tsx │ │ │ │ │ ├── FooterNav.tsx │ │ │ │ │ └── FooterText.tsx │ │ │ │ └── landing-sections │ │ │ │ │ ├── CtaButtons.tsx │ │ │ │ │ ├── SectionContact.tsx │ │ │ │ │ ├── SectionContent.tsx │ │ │ │ │ ├── SectionCta.tsx │ │ │ │ │ ├── SectionFaq.tsx │ │ │ │ │ ├── SectionFeatures.tsx │ │ │ │ │ ├── SectionHero.tsx │ │ │ │ │ ├── SectionPosts.tsx │ │ │ │ │ ├── SectionPricing.tsx │ │ │ │ │ └── SectionReviews.tsx │ │ │ ├── layouts │ │ │ │ ├── BlogLayout.tsx │ │ │ │ ├── LandingLayout.tsx │ │ │ │ ├── PageLayout.tsx │ │ │ │ └── PostLayout.tsx │ │ │ ├── pages │ │ │ │ ├── [[...slug]].tsx │ │ │ │ └── _app.tsx │ │ │ ├── sass │ │ │ │ ├── imports │ │ │ │ │ ├── _banner.scss │ │ │ │ │ ├── _buttons.scss │ │ │ │ │ ├── _footer.scss │ │ │ │ │ ├── _forms.scss │ │ │ │ │ ├── _functions.scss │ │ │ │ │ ├── _general.scss │ │ │ │ │ ├── _header.scss │ │ │ │ │ ├── _helpers.scss │ │ │ │ │ ├── _icons.scss │ │ │ │ │ ├── _menus.scss │ │ │ │ │ ├── _palettes.scss │ │ │ │ │ ├── _posts.scss │ │ │ │ │ ├── _reset.scss │ │ │ │ │ ├── _sections.scss │ │ │ │ │ ├── _structure.scss │ │ │ │ │ ├── _tables.scss │ │ │ │ │ └── _variables.scss │ │ │ │ └── main.scss │ │ │ └── utils │ │ │ │ ├── classNames.tsx │ │ │ │ ├── htmlToReact.tsx │ │ │ │ ├── index.ts │ │ │ │ ├── link.tsx │ │ │ │ ├── markdownify.js │ │ │ │ ├── next.ts │ │ │ │ └── withPrefix.ts │ │ └── tsconfig.json │ ├── playground-azimuth-sanity │ │ ├── .gitignore │ │ ├── copy-code.sh │ │ ├── package.json │ │ ├── studio │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── config │ │ │ │ ├── .checksums │ │ │ │ └── @sanity │ │ │ │ │ ├── data-aspects.json │ │ │ │ │ ├── default-layout.json │ │ │ │ │ ├── default-login.json │ │ │ │ │ └── form-builder.json │ │ │ ├── deskStructure.js │ │ │ ├── migrations │ │ │ │ └── migrate.js │ │ │ ├── package.json │ │ │ ├── plugins │ │ │ │ └── .gitkeep │ │ │ ├── sanity.json │ │ │ ├── schemas │ │ │ │ ├── action.js │ │ │ │ ├── blog.js │ │ │ │ ├── config.js │ │ │ │ ├── faq_item.js │ │ │ │ ├── feature_item.js │ │ │ │ ├── footer.js │ │ │ │ ├── footer_form.js │ │ │ │ ├── footer_nav.js │ │ │ │ ├── footer_text.js │ │ │ │ ├── form_field.js │ │ │ │ ├── header.js │ │ │ │ ├── landing.js │ │ │ │ ├── page.js │ │ │ │ ├── person.js │ │ │ │ ├── post.js │ │ │ │ ├── pricing_plan.js │ │ │ │ ├── review_item.js │ │ │ │ ├── schema.js │ │ │ │ ├── section_contact.js │ │ │ │ ├── section_content.js │ │ │ │ ├── section_cta.js │ │ │ │ ├── section_faq.js │ │ │ │ ├── section_features.js │ │ │ │ ├── section_hero.js │ │ │ │ ├── section_posts.js │ │ │ │ ├── section_pricing.js │ │ │ │ ├── section_reviews.js │ │ │ │ └── seo.js │ │ │ ├── static │ │ │ │ ├── .gitkeep │ │ │ │ └── favicon.ico │ │ │ └── tsconfig.json │ │ └── web │ │ │ ├── contentlayer │ │ │ └── contentlayer.ts │ │ │ ├── dev.js │ │ │ ├── entries.json │ │ │ ├── next.config.js │ │ │ ├── package.json │ │ │ └── tsconfig.json │ ├── playground-azimuth │ │ ├── content │ │ │ ├── data │ │ │ │ ├── authors │ │ │ │ │ ├── jane-doe.yaml │ │ │ │ │ └── john-doe.yaml │ │ │ │ └── config.json │ │ │ └── pages │ │ │ │ ├── about.md │ │ │ │ ├── blog.md │ │ │ │ ├── blog │ │ │ │ ├── azimuth-improvements.md │ │ │ │ ├── customer-loyalty.md │ │ │ │ ├── customer-service-skills-that-every-employee-needs.md │ │ │ │ ├── design-azimuth.md │ │ │ │ ├── design-team-collaborates.md │ │ │ │ ├── sales-as-service.md │ │ │ │ ├── set-big-goals.md │ │ │ │ ├── user-journey-mapping.md │ │ │ │ └── working-from-home.md │ │ │ │ ├── contact.md │ │ │ │ ├── features.md │ │ │ │ ├── index.md │ │ │ │ ├── pricing.md │ │ │ │ ├── privacy-policy.md │ │ │ │ ├── signup.md │ │ │ │ ├── style-guide.md │ │ │ │ └── terms-of-service.md │ │ ├── contentlayer.config.ts │ │ ├── next-env.d.ts │ │ ├── next.config.js │ │ ├── package.json │ │ ├── public │ │ │ ├── images │ │ │ │ ├── 1.jpg │ │ │ │ ├── 10.jpg │ │ │ │ ├── 10_thumb.jpg │ │ │ │ ├── 11.jpg │ │ │ │ ├── 11_thumb.jpg │ │ │ │ ├── 12.jpg │ │ │ │ ├── 12_thumb.jpg │ │ │ │ ├── 1_thumb.jpg │ │ │ │ ├── 2.jpg │ │ │ │ ├── 2_thumb.jpg │ │ │ │ ├── 3.jpg │ │ │ │ ├── 3_thumb.jpg │ │ │ │ ├── 4.jpg │ │ │ │ ├── 4_thumb.jpg │ │ │ │ ├── 5.jpg │ │ │ │ ├── 5_thumb.jpg │ │ │ │ ├── 6.jpg │ │ │ │ ├── 6_thumb.jpg │ │ │ │ ├── 7.jpg │ │ │ │ ├── 7_thumb.jpg │ │ │ │ ├── 8.jpg │ │ │ │ ├── 8_thumb.jpg │ │ │ │ ├── 9.jpg │ │ │ │ ├── 9_thumb.jpg │ │ │ │ ├── about.jpg │ │ │ │ ├── author.jpg │ │ │ │ ├── avatar.png │ │ │ │ ├── favicon.png │ │ │ │ ├── feature1.png │ │ │ │ ├── feature2.png │ │ │ │ ├── feature3.png │ │ │ │ ├── hero.png │ │ │ │ ├── intro.jpg │ │ │ │ ├── logo-alt.svg │ │ │ │ ├── logo.svg │ │ │ │ ├── review1.jpg │ │ │ │ ├── review2.jpg │ │ │ │ └── review3.jpg │ │ │ └── js │ │ │ │ ├── init.js │ │ │ │ ├── main.js │ │ │ │ └── plugins.js │ │ ├── src │ │ │ ├── components │ │ │ │ ├── Action.tsx │ │ │ │ ├── ActionLink.tsx │ │ │ │ ├── BlogPostFooter.tsx │ │ │ │ ├── FormField.tsx │ │ │ │ ├── Header.tsx │ │ │ │ ├── Icon.tsx │ │ │ │ ├── Layout.tsx │ │ │ │ ├── footer │ │ │ │ │ ├── Footer.tsx │ │ │ │ │ ├── FooterForm.tsx │ │ │ │ │ ├── FooterNav.tsx │ │ │ │ │ └── FooterText.tsx │ │ │ │ └── landing-sections │ │ │ │ │ ├── CtaButtons.tsx │ │ │ │ │ ├── SectionContact.tsx │ │ │ │ │ ├── SectionContent.tsx │ │ │ │ │ ├── SectionCta.tsx │ │ │ │ │ ├── SectionFaq.tsx │ │ │ │ │ ├── SectionFeatures.tsx │ │ │ │ │ ├── SectionHero.tsx │ │ │ │ │ ├── SectionPosts.tsx │ │ │ │ │ ├── SectionPricing.tsx │ │ │ │ │ └── SectionReviews.tsx │ │ │ ├── contentlayer │ │ │ │ ├── documents │ │ │ │ │ ├── Blog.ts │ │ │ │ │ ├── Config.ts │ │ │ │ │ ├── Landing.ts │ │ │ │ │ ├── Page.ts │ │ │ │ │ ├── Person.ts │ │ │ │ │ └── Post.ts │ │ │ │ ├── index.ts │ │ │ │ ├── nested │ │ │ │ │ ├── Action.ts │ │ │ │ │ ├── FormField.ts │ │ │ │ │ └── SEO.ts │ │ │ │ └── utils.ts │ │ │ ├── layouts │ │ │ │ ├── BlogLayout.tsx │ │ │ │ ├── LandingLayout.tsx │ │ │ │ ├── PageLayout.tsx │ │ │ │ └── PostLayout.tsx │ │ │ ├── pages │ │ │ │ ├── [[...slug]].tsx │ │ │ │ └── _app.tsx │ │ │ ├── sass │ │ │ │ ├── imports │ │ │ │ │ ├── _banner.scss │ │ │ │ │ ├── _buttons.scss │ │ │ │ │ ├── _footer.scss │ │ │ │ │ ├── _forms.scss │ │ │ │ │ ├── _functions.scss │ │ │ │ │ ├── _general.scss │ │ │ │ │ ├── _header.scss │ │ │ │ │ ├── _helpers.scss │ │ │ │ │ ├── _icons.scss │ │ │ │ │ ├── _menus.scss │ │ │ │ │ ├── _palettes.scss │ │ │ │ │ ├── _posts.scss │ │ │ │ │ ├── _reset.scss │ │ │ │ │ ├── _sections.scss │ │ │ │ │ ├── _structure.scss │ │ │ │ │ ├── _tables.scss │ │ │ │ │ └── _variables.scss │ │ │ │ └── main.scss │ │ │ └── utils │ │ │ │ ├── classNames.tsx │ │ │ │ ├── htmlToReact.tsx │ │ │ │ ├── index.ts │ │ │ │ ├── link.tsx │ │ │ │ ├── markdownify.js │ │ │ │ ├── next.ts │ │ │ │ └── withPrefix.ts │ │ ├── stackbit.yaml │ │ └── tsconfig.json │ ├── playground-contentful-starter │ │ ├── .gitignore │ │ ├── .gitpod.yml │ │ ├── README.md │ │ ├── components │ │ │ ├── date.tsx │ │ │ ├── layout.module.css │ │ │ └── layout.tsx │ │ ├── contentlayer.config.ts │ │ ├── next-env.d.ts │ │ ├── next.config.js │ │ ├── package.json │ │ ├── pages │ │ │ ├── _app.tsx │ │ │ ├── index.tsx │ │ │ └── posts │ │ │ │ └── [id].tsx │ │ ├── public │ │ │ ├── favicon.ico │ │ │ └── images │ │ │ │ └── profile.jpg │ │ ├── stackbit.yaml │ │ ├── styles │ │ │ ├── global.css │ │ │ └── utils.module.css │ │ └── tsconfig.json │ ├── starter-js │ │ ├── .gitignore │ │ ├── README.md │ │ ├── components │ │ │ ├── date.jsx │ │ │ ├── layout.jsx │ │ │ └── layout.module.css │ │ ├── contentlayer.config.js │ │ ├── jsconfig.json │ │ ├── next.config.js │ │ ├── package.json │ │ ├── pages │ │ │ ├── _app.jsx │ │ │ ├── index.jsx │ │ │ └── posts │ │ │ │ └── [id].jsx │ │ ├── posts │ │ │ ├── pre-rendering.md │ │ │ └── ssg-ssr.md │ │ ├── public │ │ │ ├── favicon.ico │ │ │ └── images │ │ │ │ └── profile.jpg │ │ └── styles │ │ │ ├── global.css │ │ │ └── utils.module.css │ └── starter │ │ ├── README.md │ │ ├── components │ │ ├── date.tsx │ │ ├── layout.module.css │ │ └── layout.tsx │ │ ├── contentlayer.config.ts │ │ ├── next-env.d.ts │ │ ├── next.config.js │ │ ├── package.json │ │ ├── pages │ │ ├── _app.tsx │ │ ├── index.tsx │ │ └── posts │ │ │ └── [id].tsx │ │ ├── posts │ │ ├── pre-rendering.md │ │ └── ssg-ssr.md │ │ ├── public │ │ ├── favicon.ico │ │ └── images │ │ │ └── profile.jpg │ │ ├── styles │ │ ├── global.css │ │ └── utils.module.css │ │ └── tsconfig.json ├── next-images │ ├── .gitignore │ ├── app │ │ ├── layout.tsx │ │ ├── page.tsx │ │ └── posts │ │ │ └── [slug] │ │ │ └── page.tsx │ ├── components │ │ ├── Button.tsx │ │ └── Header.tsx │ ├── contentlayer.config.ts │ ├── next-env.d.ts │ ├── next.config.js │ ├── package.json │ ├── postcss.config.js │ ├── posts │ │ ├── change-me.mdx │ │ ├── click-me.mdx │ │ └── what-is-contentlayer.mdx │ ├── public │ │ └── images │ │ │ ├── favicon.png │ │ │ └── mark-neal-unsplash.jpg │ ├── styles │ │ └── globals.css │ ├── tailwind.config.js │ └── tsconfig.json ├── next-rsc-dynamic │ ├── .gitignore │ ├── .vscode │ │ └── settings.json │ ├── README.md │ ├── app │ │ ├── [...slug] │ │ │ ├── head.tsx │ │ │ └── page.tsx │ │ ├── layout.tsx │ │ ├── page.tsx │ │ └── v │ │ │ ├── [tag] │ │ │ ├── [...slug] │ │ │ │ └── page.tsx │ │ │ └── page.tsx │ │ │ └── page.tsx │ ├── components │ │ ├── Button.tsx │ │ └── Header.tsx │ ├── content │ │ └── .gitkeep │ ├── contentlayer.config.ts │ ├── next-env.d.ts │ ├── next.config.js │ ├── package.json │ ├── postcss.config.js │ ├── posts │ │ ├── change-me.md │ │ ├── click-me.md │ │ └── what-is-contentlayer.md │ ├── public │ │ └── images │ │ │ └── favicon.png │ ├── styles │ │ └── globals.css │ ├── tailwind.config.js │ └── tsconfig.json ├── node-script-mdx │ ├── contentlayer.config.ts │ ├── my-script.mjs │ ├── package.json │ └── posts │ │ ├── change-me.mdx │ │ ├── click-me.mdx │ │ └── what-is-contentlayer.mdx ├── node-script-remote-content │ ├── .gitignore │ ├── contentlayer.config.ts │ ├── my-script.mjs │ └── package.json └── node-script │ ├── contentlayer.config.ts │ ├── my-script.mjs │ ├── package.json │ └── posts │ ├── change-me.md │ ├── click-me.md │ └── what-is-contentlayer.md ├── flake.lock ├── flake.nix ├── package.json ├── packages ├── @contentlayer │ ├── cli │ │ ├── README.md │ │ ├── package.json │ │ ├── src │ │ │ ├── commands │ │ │ │ ├── BuildCommand.ts │ │ │ │ ├── DefaultCommand.ts │ │ │ │ ├── DevCommand.ts │ │ │ │ ├── PostInstallCommand.ts │ │ │ │ └── _BaseCommand.ts │ │ │ ├── global.d.ts │ │ │ ├── index.ts │ │ │ └── lib │ │ │ │ └── utils.ts │ │ └── tsconfig.json │ ├── client │ │ ├── .gitignore │ │ ├── package.json │ │ ├── src │ │ │ ├── guards.ts │ │ │ ├── index.ts │ │ │ └── utils.ts │ │ └── tsconfig.json │ ├── core │ │ ├── package.json │ │ ├── src │ │ │ ├── ArtifactsDir.ts │ │ │ ├── DataCache.ts │ │ │ ├── _ArtifactsDir.ts │ │ │ ├── ambient.d.ts │ │ │ ├── cwd.ts │ │ │ ├── data-types.ts │ │ │ ├── dynamic-build.ts │ │ │ ├── errors.ts │ │ │ ├── gen.ts │ │ │ ├── generation │ │ │ │ ├── common.ts │ │ │ │ ├── generate-dotpkg.ts │ │ │ │ └── generate-types.ts │ │ │ ├── getConfig │ │ │ │ ├── esbuild.ts │ │ │ │ └── index.ts │ │ │ ├── index.ts │ │ │ ├── markdown │ │ │ │ ├── markdown.ts │ │ │ │ ├── mdx.ts │ │ │ │ └── unified.ts │ │ │ ├── plugin.ts │ │ │ ├── runMain.ts │ │ │ ├── schema │ │ │ │ ├── field.ts │ │ │ │ ├── index.ts │ │ │ │ ├── stackbit-extension.ts │ │ │ │ └── validate.ts │ │ │ └── validate-tsconfig.ts │ │ └── tsconfig.json │ ├── experimental-source-files-stackbit │ │ ├── package.json │ │ ├── src │ │ │ ├── __test__ │ │ │ │ ├── __snapshots__ │ │ │ │ │ └── stackbit.spec.ts.snap │ │ │ │ ├── fixtures │ │ │ │ │ ├── kitchen-sink │ │ │ │ │ │ ├── .stackbit │ │ │ │ │ │ │ └── models │ │ │ │ │ │ │ │ ├── data_model_1.yaml │ │ │ │ │ │ │ │ ├── data_model_2.yaml │ │ │ │ │ │ │ │ ├── object_model_1.yaml │ │ │ │ │ │ │ │ ├── object_model_2.yaml │ │ │ │ │ │ │ │ ├── page_kitchen_sink.yaml │ │ │ │ │ │ │ │ ├── page_model_1.yaml │ │ │ │ │ │ │ │ └── page_model_2.yaml │ │ │ │ │ │ └── stackbit.yaml │ │ │ │ │ ├── next-starter │ │ │ │ │ │ ├── .stackbit │ │ │ │ │ │ │ └── models │ │ │ │ │ │ │ │ ├── Button.yaml │ │ │ │ │ │ │ │ ├── Card.yaml │ │ │ │ │ │ │ │ ├── CardGridSection.yaml │ │ │ │ │ │ │ │ ├── FooterConfig.yaml │ │ │ │ │ │ │ │ ├── HeroSection.yaml │ │ │ │ │ │ │ │ ├── Page.yaml │ │ │ │ │ │ │ │ └── SiteConfig.yaml │ │ │ │ │ │ └── stackbit.yaml │ │ │ │ │ └── small-business │ │ │ │ │ │ ├── .stackbit │ │ │ │ │ │ └── models │ │ │ │ │ │ │ ├── BackgroundImage.yaml │ │ │ │ │ │ │ ├── Button.yaml │ │ │ │ │ │ │ ├── CheckboxFormControl.yaml │ │ │ │ │ │ │ ├── Config.yaml │ │ │ │ │ │ │ ├── ContactBlock.yaml │ │ │ │ │ │ │ ├── ContactSection.yaml │ │ │ │ │ │ │ ├── CtaSection.yaml │ │ │ │ │ │ │ ├── DividerSection.yaml │ │ │ │ │ │ │ ├── EmailFormControl.yaml │ │ │ │ │ │ │ ├── FeatureHighlightSection.yaml │ │ │ │ │ │ │ ├── FeaturedItem.yaml │ │ │ │ │ │ │ ├── FeaturedItemsSection.yaml │ │ │ │ │ │ │ ├── FeaturedPeopleSection.yaml │ │ │ │ │ │ │ ├── FeaturedPostsSection.yaml │ │ │ │ │ │ │ ├── Footer.yaml │ │ │ │ │ │ │ ├── FormBlock.yaml │ │ │ │ │ │ │ ├── Header.yaml │ │ │ │ │ │ │ ├── HeroSection.yaml │ │ │ │ │ │ │ ├── ImageBlock.yaml │ │ │ │ │ │ │ ├── Link.yaml │ │ │ │ │ │ │ ├── MediaGallerySection.yaml │ │ │ │ │ │ │ ├── MetaTag.yaml │ │ │ │ │ │ │ ├── PageLayout.yaml │ │ │ │ │ │ │ ├── PagedPostsSection.yaml │ │ │ │ │ │ │ ├── Person.yaml │ │ │ │ │ │ │ ├── PostFeedLayout.yaml │ │ │ │ │ │ │ ├── PostFeedSection.yaml │ │ │ │ │ │ │ ├── PostLayout.yaml │ │ │ │ │ │ │ ├── QuoteSection.yaml │ │ │ │ │ │ │ ├── RecentPostsSection.yaml │ │ │ │ │ │ │ ├── Section.yaml │ │ │ │ │ │ │ ├── SelectFormControl.yaml │ │ │ │ │ │ │ ├── Seo.yaml │ │ │ │ │ │ │ ├── Social.yaml │ │ │ │ │ │ │ ├── Testimonial.yaml │ │ │ │ │ │ │ ├── TestimonialsSection.yaml │ │ │ │ │ │ │ ├── TextFormControl.yaml │ │ │ │ │ │ │ ├── TextSection.yaml │ │ │ │ │ │ │ ├── TextareaFormControl.yaml │ │ │ │ │ │ │ ├── ThemeStyle.yaml │ │ │ │ │ │ │ └── VideoBlock.yaml │ │ │ │ │ │ └── stackbit.yaml │ │ │ │ └── stackbit.spec.ts │ │ │ ├── index.ts │ │ │ └── mapping.ts │ │ └── tsconfig.json │ ├── source-contentful │ │ ├── package.json │ │ ├── src │ │ │ ├── contentful.ts │ │ │ ├── errors.ts │ │ │ ├── fetchData │ │ │ │ ├── index.ts │ │ │ │ └── mapping.ts │ │ │ ├── index.ts │ │ │ ├── provideSchema.ts │ │ │ ├── schemaOverrides.ts │ │ │ └── types.ts │ │ └── tsconfig.json │ ├── source-files │ │ ├── package.json │ │ ├── src │ │ │ ├── __test__ │ │ │ │ ├── errors │ │ │ │ │ ├── aggregate.spec.ts │ │ │ │ │ └── utils.ts │ │ │ │ ├── fetchData │ │ │ │ │ ├── fixtures │ │ │ │ │ │ ├── 3-small-files │ │ │ │ │ │ │ ├── a.md │ │ │ │ │ │ │ ├── b.md │ │ │ │ │ │ │ └── c.md │ │ │ │ │ │ └── misc-files │ │ │ │ │ │ │ ├── empty-json │ │ │ │ │ │ │ └── empty.json │ │ │ │ │ │ │ ├── empty-markdown │ │ │ │ │ │ │ └── empty.md │ │ │ │ │ │ │ ├── empty-mdx │ │ │ │ │ │ │ └── empty.mdx │ │ │ │ │ │ │ └── empty-yaml │ │ │ │ │ │ │ └── empty.yaml │ │ │ │ │ ├── makeCacheItemFromFilePath.spec.ts │ │ │ │ │ └── utils.ts │ │ │ │ ├── mapping │ │ │ │ │ ├── getDataForFieldDef.spec.ts │ │ │ │ │ └── getFlattenedPath.spec.ts │ │ │ │ └── type-generation │ │ │ │ │ ├── __snapshots__ │ │ │ │ │ └── basic.spec.ts.snap │ │ │ │ │ └── basic.spec.ts │ │ │ ├── errors │ │ │ │ ├── aggregate.ts │ │ │ │ └── index.ts │ │ │ ├── fetchData │ │ │ │ ├── DocumentContext.ts │ │ │ │ ├── DocumentTypeMap.ts │ │ │ │ ├── fetchAllDocuments.ts │ │ │ │ ├── index.ts │ │ │ │ ├── makeCacheItemFromFilePath.ts │ │ │ │ ├── mapping │ │ │ │ │ ├── field-date.ts │ │ │ │ │ ├── field-image.ts │ │ │ │ │ ├── field-markdown.ts │ │ │ │ │ ├── field-mdx.ts │ │ │ │ │ ├── imagescript.d.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ └── parseFieldData.ts │ │ │ │ ├── types.ts │ │ │ │ └── validateDocumentData.ts │ │ │ ├── index.ts │ │ │ ├── schema │ │ │ │ ├── defs │ │ │ │ │ ├── computed-field.ts │ │ │ │ │ ├── field.ts │ │ │ │ │ └── index.ts │ │ │ │ └── provideSchema.ts │ │ │ └── types.ts │ │ └── tsconfig.json │ ├── source-remote-files │ │ ├── package.json │ │ ├── src │ │ │ └── index.ts │ │ └── tsconfig.json │ └── utils │ │ ├── node.js │ │ ├── package.json │ │ ├── src │ │ ├── base64.ts │ │ ├── effect │ │ │ ├── Array.ts │ │ │ ├── Chunk.ts │ │ │ ├── ConsoleService.ts │ │ │ ├── Effect.ts │ │ │ ├── OT.ts │ │ │ ├── Option.ts │ │ │ ├── Stream.ts │ │ │ ├── These.ts │ │ │ ├── Tracing │ │ │ │ └── Enable.ts │ │ │ └── index.ts │ │ ├── file-paths.ts │ │ ├── fs-in-memory.ts │ │ ├── fs.ts │ │ ├── fs_.ts │ │ ├── guards.ts │ │ ├── hash.ts │ │ ├── index.ts │ │ ├── node │ │ │ ├── fs-watcher.ts │ │ │ ├── fs.ts │ │ │ ├── index.ts │ │ │ └── version.ts │ │ ├── object │ │ │ ├── index.ts │ │ │ ├── omit.ts │ │ │ └── pick.ts │ │ ├── promise.ts │ │ ├── single-item.ts │ │ ├── string.ts │ │ ├── tracing-effect │ │ │ └── index.ts │ │ └── tracing.ts │ │ └── tsconfig.json ├── archive │ └── source-sanity │ │ ├── package.json │ │ ├── src │ │ ├── fetchData.ts │ │ ├── index.ts │ │ ├── provideSchema.ts │ │ ├── sanity-client.ts │ │ ├── sanity-types.ts │ │ └── types.ts │ │ └── tsconfig.json ├── contentful-generator │ ├── package.json │ ├── src │ │ ├── index.ts │ │ └── migration.ts │ └── tsconfig.json ├── contentlayer-stackbit-yaml-generator │ ├── bin │ │ └── cli.cjs │ ├── package.json │ ├── src │ │ ├── __test__ │ │ │ ├── __snapshots__ │ │ │ │ └── convert.spec.ts.snap │ │ │ ├── convert.spec.ts │ │ │ └── fixtures │ │ │ │ ├── azimuth-schema │ │ │ │ ├── documents │ │ │ │ │ ├── Blog.ts │ │ │ │ │ ├── Config.ts │ │ │ │ │ ├── Landing.ts │ │ │ │ │ ├── Page.ts │ │ │ │ │ ├── Person.ts │ │ │ │ │ └── Post.ts │ │ │ │ ├── index.ts │ │ │ │ ├── nested │ │ │ │ │ ├── Action.ts │ │ │ │ │ ├── FormField.ts │ │ │ │ │ └── SEO.ts │ │ │ │ └── utils.ts │ │ │ │ ├── blog-schema │ │ │ │ └── index.ts │ │ │ │ └── index.ts │ │ ├── cli │ │ │ ├── DefaultCommand.ts │ │ │ ├── convert.ts │ │ │ ├── index.ts │ │ │ └── utils.ts │ │ └── lib │ │ │ └── index.ts │ └── tsconfig.json ├── contentlayer │ ├── README.md │ ├── bin │ │ └── cli.cjs │ ├── index.d.ts │ ├── package.json │ ├── src │ │ ├── client │ │ │ └── index.ts │ │ ├── core │ │ │ └── index.ts │ │ ├── source-files │ │ │ ├── index.ts │ │ │ └── schema │ │ │ │ └── index.ts │ │ ├── source-remote-files │ │ │ └── index.ts │ │ └── utils │ │ │ ├── index.ts │ │ │ └── node │ │ │ └── index.ts │ └── tsconfig.json ├── integration-tests │ ├── README.md │ ├── package.json │ ├── src │ │ ├── empty-content-folder │ │ │ ├── index.test.ts │ │ │ └── posts │ │ │ │ └── .gitkeep │ │ ├── image-field │ │ │ ├── content │ │ │ │ └── posts │ │ │ │ │ ├── image-a.png │ │ │ │ │ └── post-a.md │ │ │ └── index.test.ts │ │ ├── markdown │ │ │ ├── index.test.ts │ │ │ └── posts │ │ │ │ └── post-1.md │ │ └── mdx-remark-images │ │ │ ├── content │ │ │ └── posts │ │ │ │ ├── image-a.png │ │ │ │ └── post-a.mdx │ │ │ ├── contentDirPath │ │ │ └── posts │ │ │ │ ├── image-b.png │ │ │ │ └── post-b.mdx │ │ │ └── index.test.ts │ ├── tsconfig.json │ └── vitest.config.ts └── next-contentlayer │ ├── package.json │ ├── src │ ├── ambient.d.ts │ ├── check-constraints.ts │ ├── hooks │ │ ├── index.ts │ │ ├── jsx-runtime.cjs │ │ ├── useLiveReload.ts │ │ └── useMDXComponent.ts │ ├── index-cjs.ts │ ├── index.ts │ └── plugin.ts │ └── tsconfig.json ├── prettier.config.js ├── tsconfig.all.json ├── tsconfig.base.json ├── vercel.json └── yarn.lock /.changeset/README.md: -------------------------------------------------------------------------------- 1 | # Changesets 2 | 3 | Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works 4 | with multi-package repos, or single-package repos to help you version and publish your code. You can 5 | find the full documentation for it [in our repository](https://github.com/changesets/changesets) 6 | 7 | We have a quick list of common questions to get you started engaging with this project in 8 | [our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md) 9 | -------------------------------------------------------------------------------- /.changeset/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://unpkg.com/@changesets/config@1.6.1/schema.json", 3 | "changelog": "@changesets/cli/changelog", 4 | "commit": false, 5 | "fixed": [["@contentlayer/*", "contentlayer", "next-contentlayer"]], 6 | "access": "public", 7 | "baseBranch": "main", 8 | "updateInternalDependencies": "patch", 9 | "ignore": ["examples-*"], 10 | "___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH": { 11 | "useCalculatedVersionForSnapshots": true 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /.envrc: -------------------------------------------------------------------------------- 1 | if test -f ./.envrc.local; then 2 | source_env ./.envrc.local 3 | fi 4 | 5 | if command -v nix-shell &> /dev/null 6 | then 7 | use_flake 8 | fi 9 | 10 | export CONTENTLAYER_TRACING="collector" 11 | export CL_OTEL=1 12 | 13 | # Put the following in `.envrc.local` 14 | # export CONTENTFUL_ACCESS_TOKEN="" 15 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /.yarn/* 2 | !/.yarn/releases 3 | !/.yarn/plugins 4 | !/.yarn/sdks 5 | 6 | # Swap the comments on the following lines if you don't wish to use zero-installs 7 | # Documentation here: https://yarnpkg.com/features/zero-installs 8 | # !/.yarn/cache 9 | #/.pnp.* 10 | node_modules 11 | .next 12 | 13 | dist* 14 | out 15 | 16 | .tmp* 17 | /tmp 18 | 19 | *.tsbuildinfo 20 | 21 | .envrc.local 22 | .direnv 23 | 24 | .nyc_output 25 | 26 | !tap-snapshots/dist/* 27 | 28 | .contentlayer 29 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "examples/next-contentlayer-example"] 2 | path = examples/next-contentlayer-example 3 | url = git@github.com:contentlayerdev/next-contentlayer-example.git 4 | -------------------------------------------------------------------------------- /.gitpod.yml: -------------------------------------------------------------------------------- 1 | tasks: 2 | - init: yarn install && yarn build && yarn examples:postinstall 3 | github: 4 | prebuilds: 5 | addCheck: true 6 | -------------------------------------------------------------------------------- /.infra/.gitignore: -------------------------------------------------------------------------------- 1 | tempo-data -------------------------------------------------------------------------------- /.infra/grafana-datasources.yml: -------------------------------------------------------------------------------- 1 | apiVersion: 1 2 | 3 | datasources: 4 | - name: Prometheus 5 | type: prometheus 6 | access: proxy 7 | orgId: 1 8 | url: http://prometheus:9090 9 | basicAuth: false 10 | isDefault: false 11 | version: 1 12 | editable: false 13 | jsonData: 14 | exemplarTraceIdDestinations: 15 | - datasourceUid: tempo 16 | name: 'traceID' 17 | uid: prometheus 18 | - name: Tempo 19 | type: tempo 20 | access: proxy 21 | orgId: 1 22 | url: http://tempo:3200 23 | basicAuth: false 24 | isDefault: true 25 | version: 1 26 | editable: false 27 | apiVersion: 1 28 | jsonData: 29 | serviceMap: 30 | datasourceUid: prometheus 31 | uid: tempo 32 | -------------------------------------------------------------------------------- /.infra/grafana.ini: -------------------------------------------------------------------------------- 1 | # NOTE currently Tempo search is still behind a feature flag. This file can probably be removed in the future. 2 | [feature_toggles] 3 | enable = tempoSearch tempoBackendSearch -------------------------------------------------------------------------------- /.infra/otel-collector.yml: -------------------------------------------------------------------------------- 1 | receivers: 2 | otlp: 3 | protocols: 4 | grpc: 5 | http: 6 | cors: 7 | allowed_origins: 8 | - 'http://*' 9 | - 'https://*' 10 | allowed_headers: ['*'] 11 | 12 | exporters: 13 | otlp: 14 | endpoint: tempo:4317 15 | tls: 16 | insecure: true 17 | jaeger: 18 | endpoint: jaeger-all-in-one:14250 19 | tls: 20 | insecure: true 21 | prometheus: 22 | endpoint: "0.0.0.0:8889" 23 | 24 | # TODO should I re-enable the batch processor? 25 | # processors: 26 | # batch: 27 | 28 | service: 29 | pipelines: 30 | traces: 31 | receivers: [otlp] 32 | exporters: [otlp, jaeger] 33 | # processors: [batch] 34 | metrics: 35 | receivers: [otlp] 36 | exporters: [prometheus] 37 | -------------------------------------------------------------------------------- /.infra/prometheus.yml: -------------------------------------------------------------------------------- 1 | global: 2 | scrape_interval: 15s # Set the scrape interval to every 15 seconds. Default is every 1 minute. 3 | evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute. 4 | 5 | scrape_configs: 6 | - job_name: "prometheus" 7 | scrape_interval: 5s 8 | static_configs: 9 | - targets: ["localhost:9090"] 10 | 11 | - job_name: "tempo" 12 | static_configs: 13 | - targets: ["tempo:3200"] 14 | 15 | - job_name: "oltp-metrics" 16 | static_configs: 17 | - targets: ["otel-collector:8889"] -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | packages/_archive/* 2 | **/.contentlayer/* 3 | **/fixtures/**/*.yaml 4 | **/dist/* 5 | **/.nyc_output/* -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "arcanis.vscode-zipfs" 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /.vscode/operators.code-snippets: -------------------------------------------------------------------------------- 1 | { 2 | "Pipe Operator |": { 3 | "prefix": "|", 4 | "body": ["[\"|>\"]($0)"], 5 | "description": "Pipe Operator" 6 | }, 7 | "Gen Function": { 8 | "prefix": "gen", 9 | "body": ["function* ($) {}"], 10 | "description": "Generator FUnction with $ input" 11 | }, 12 | "Gen Yield * tmp": { 13 | "prefix": "yy", 14 | "body": ["yield* $($0)"], 15 | "description": "Yield generator calling $()" 16 | }, 17 | "Gen Yield *": { 18 | "prefix": "!", 19 | "body": ["yield* $($0)"], 20 | "description": "Yield generator calling $()" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /.yarn/sdks/integrations.yml: -------------------------------------------------------------------------------- 1 | # This file is automatically generated by PnPify. 2 | # Manual changes will be lost! 3 | 4 | integrations: 5 | - vscode 6 | -------------------------------------------------------------------------------- /.yarn/sdks/typescript/bin/tsc: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | const {existsSync} = require(`fs`); 4 | const {createRequire, createRequireFromPath} = require(`module`); 5 | const {resolve} = require(`path`); 6 | 7 | const relPnpApiPath = "../../../../.pnp.js"; 8 | 9 | const absPnpApiPath = resolve(__dirname, relPnpApiPath); 10 | const absRequire = (createRequire || createRequireFromPath)(absPnpApiPath); 11 | 12 | if (existsSync(absPnpApiPath)) { 13 | if (!process.versions.pnp) { 14 | // Setup the environment to be able to require typescript/bin/tsc 15 | require(absPnpApiPath).setup(); 16 | } 17 | } 18 | 19 | // Defer to the real typescript/bin/tsc your application uses 20 | module.exports = absRequire(`typescript/bin/tsc`); 21 | -------------------------------------------------------------------------------- /.yarn/sdks/typescript/bin/tsserver: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | const {existsSync} = require(`fs`); 4 | const {createRequire, createRequireFromPath} = require(`module`); 5 | const {resolve} = require(`path`); 6 | 7 | const relPnpApiPath = "../../../../.pnp.js"; 8 | 9 | const absPnpApiPath = resolve(__dirname, relPnpApiPath); 10 | const absRequire = (createRequire || createRequireFromPath)(absPnpApiPath); 11 | 12 | if (existsSync(absPnpApiPath)) { 13 | if (!process.versions.pnp) { 14 | // Setup the environment to be able to require typescript/bin/tsserver 15 | require(absPnpApiPath).setup(); 16 | } 17 | } 18 | 19 | // Defer to the real typescript/bin/tsserver your application uses 20 | module.exports = absRequire(`typescript/bin/tsserver`); 21 | -------------------------------------------------------------------------------- /.yarn/sdks/typescript/lib/tsc.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | const {existsSync} = require(`fs`); 4 | const {createRequire, createRequireFromPath} = require(`module`); 5 | const {resolve} = require(`path`); 6 | 7 | const relPnpApiPath = "../../../../.pnp.js"; 8 | 9 | const absPnpApiPath = resolve(__dirname, relPnpApiPath); 10 | const absRequire = (createRequire || createRequireFromPath)(absPnpApiPath); 11 | 12 | if (existsSync(absPnpApiPath)) { 13 | if (!process.versions.pnp) { 14 | // Setup the environment to be able to require typescript/lib/tsc.js 15 | require(absPnpApiPath).setup(); 16 | } 17 | } 18 | 19 | // Defer to the real typescript/lib/tsc.js your application uses 20 | module.exports = absRequire(`typescript/lib/tsc.js`); 21 | -------------------------------------------------------------------------------- /.yarn/sdks/typescript/lib/typescript.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | const {existsSync} = require(`fs`); 4 | const {createRequire, createRequireFromPath} = require(`module`); 5 | const {resolve} = require(`path`); 6 | 7 | const relPnpApiPath = "../../../../.pnp.js"; 8 | 9 | const absPnpApiPath = resolve(__dirname, relPnpApiPath); 10 | const absRequire = (createRequire || createRequireFromPath)(absPnpApiPath); 11 | 12 | if (existsSync(absPnpApiPath)) { 13 | if (!process.versions.pnp) { 14 | // Setup the environment to be able to require typescript/lib/typescript.js 15 | require(absPnpApiPath).setup(); 16 | } 17 | } 18 | 19 | // Defer to the real typescript/lib/typescript.js your application uses 20 | module.exports = absRequire(`typescript/lib/typescript.js`); 21 | -------------------------------------------------------------------------------- /.yarn/sdks/typescript/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "typescript", 3 | "version": "4.1.3-pnpify", 4 | "main": "./lib/typescript.js", 5 | "type": "commonjs" 6 | } 7 | -------------------------------------------------------------------------------- /.yarnrc.yml: -------------------------------------------------------------------------------- 1 | changesetBaseRefs: 2 | - main 3 | - origin/main 4 | 5 | nodeLinker: node-modules 6 | 7 | npmPublishAccess: public 8 | 9 | plugins: 10 | - path: .yarn/plugins/@yarnpkg/plugin-typescript.cjs 11 | spec: "@yarnpkg/plugin-typescript" 12 | - path: .yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs 13 | spec: "@yarnpkg/plugin-interactive-tools" 14 | - path: .yarn/plugins/@yarnpkg/plugin-workspace-tools.cjs 15 | spec: "@yarnpkg/plugin-workspace-tools" 16 | - path: .yarn/plugins/@yarnpkg/plugin-version.cjs 17 | spec: "@yarnpkg/plugin-version" 18 | 19 | yarnPath: .yarn/releases/yarn-3.2.3.cjs 20 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to Contentlayer 2 | 3 | [![Gitpod Ready-to-Code](https://img.shields.io/badge/Gitpod-ready--to--code-908a85?logo=gitpod)](https://gitpod.io/#https://github.com/contentlayerdev/contentlayer) 4 | 5 | ## Development setup 6 | 7 | Contentlayer is developed as a mono-repo using Yarn. 8 | 9 | ### Cloning 10 | 11 | ```sh 12 | git clone --recurse-submodules git://github.com/contentlayerdev/contentlayer.git 13 | ``` 14 | 15 | #### Checkout submodules 16 | 17 | ```sh 18 | git submodule update --init --recursive 19 | ``` 20 | 21 | #### Installing Dependencies 22 | 23 | ```sh 24 | yarn install 25 | ``` 26 | 27 | ### Building the source 28 | 29 | ```sh 30 | # One-time build 31 | yarn build 32 | 33 | # Build and watch files for changes 34 | # ... or run `dev:ts` VSC task via `Tasks: Run Task` 35 | yarn dev:ts 36 | ``` 37 | 38 | ### Run tests 39 | 40 | ```sh 41 | yarn test 42 | ``` 43 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | packages/contentlayer/README.md -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-colocated/content/data/authors/jane-doe.yaml: -------------------------------------------------------------------------------- 1 | first_name: Jane 2 | last_name: Doe 3 | bio: >- 4 | Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor 5 | incididunt ut labore et dolore magna aliqua. Risus nullam eget felis eget nunc 6 | lobortis. Sodales ut etiam sit amet nisl purus in mollis nunc. Enim ut tellus 7 | elementum sagittis vitae. 8 | photo: images/review2.jpg 9 | -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-colocated/content/data/authors/john-doe.yaml: -------------------------------------------------------------------------------- 1 | first_name: John 2 | last_name: Doe 3 | bio: >- 4 | Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor 5 | incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis 6 | nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. 7 | photo: images/review1.jpg 8 | -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-colocated/content/pages/blog.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Blog 3 | seo: 4 | title: Blog 5 | description: This is the blog page 6 | extra: 7 | - name: 'og:type' 8 | value: website 9 | keyName: property 10 | - name: 'og:title' 11 | value: Blog 12 | keyName: property 13 | - name: 'og:description' 14 | value: This is the blog page 15 | keyName: property 16 | - name: 'og:image' 17 | value: images/1.jpg 18 | keyName: property 19 | relativeUrl: true 20 | - name: 'twitter:card' 21 | value: summary_large_image 22 | - name: 'twitter:title' 23 | value: Blog 24 | - name: 'twitter:description' 25 | value: This is the blog page 26 | - name: 'twitter:image' 27 | value: images/1.jpg 28 | relativeUrl: true 29 | --- 30 | -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-colocated/contentlayer-stackbit-yaml-generator.js: -------------------------------------------------------------------------------- 1 | const { defineTransform } = require('contentlayer-stackbit-yaml-generator') 2 | 3 | module.exports = defineTransform((config) => { 4 | config.pagesDir = 'content/pages' 5 | config.dataDir = 'content/data' 6 | 7 | config.models['Person'].folder = 'authors' 8 | config.models['Blog'].file = 'blog.md' 9 | config.models['Config'].file = 'config.json' 10 | config.models['Page'].match = ['about.md', 'privacy-policy.md', 'signup.md', 'style-guide.md', 'terms-of-service.md'] 11 | config.models['Post'].match = 'blog/**.md' 12 | config.models['Landing'].match = ['contact.md', 'features.md', 'index.md', 'pricing.md'] 13 | 14 | return config 15 | }) 16 | -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-colocated/contentlayer.config.ts: -------------------------------------------------------------------------------- 1 | import { makeSource } from 'contentlayer/source-files' 2 | import * as path from 'path' 3 | 4 | import * as schema from './src/contentlayer' 5 | 6 | export default makeSource({ 7 | contentDirPath: path.join(process.cwd(), 'content'), 8 | schema, 9 | }) 10 | -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-colocated/next-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | /// 4 | -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-colocated/next.config.js: -------------------------------------------------------------------------------- 1 | const { withContentlayer } = require('next-contentlayer') 2 | 3 | module.exports = withContentlayer({}) 4 | -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-colocated/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "examples-azimuth-colocated", 3 | "private": true, 4 | "scripts": { 5 | "dev": "next dev", 6 | "build": "next build", 7 | "start": "next start" 8 | }, 9 | "dependencies": { 10 | "date-fns": "^2.29.1", 11 | "marked": "^3.0.4", 12 | "next": "^12.2.3", 13 | "react": "^18.2.0", 14 | "react-dom": "^18.2.0", 15 | "react-helmet": "^6.1.0", 16 | "react-html-parser": "^2.0.2", 17 | "react-script-tag": "^1.1.2", 18 | "sass": "^1.32.7" 19 | }, 20 | "devDependencies": { 21 | "@types/react": "^18.0.15", 22 | "@types/react-dom": "^18.0.6", 23 | "@types/react-helmet": "^6.1.5", 24 | "contentlayer": "workspace:*", 25 | "contentlayer-stackbit-yaml-generator": "workspace:*", 26 | "next-contentlayer": "workspace:*", 27 | "typescript": "^4.7.4" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-colocated/public/images/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth-colocated/public/images/1.jpg -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-colocated/public/images/10.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth-colocated/public/images/10.jpg -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-colocated/public/images/10_thumb.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth-colocated/public/images/10_thumb.jpg -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-colocated/public/images/11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth-colocated/public/images/11.jpg -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-colocated/public/images/11_thumb.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth-colocated/public/images/11_thumb.jpg -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-colocated/public/images/12.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth-colocated/public/images/12.jpg -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-colocated/public/images/12_thumb.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth-colocated/public/images/12_thumb.jpg -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-colocated/public/images/1_thumb.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth-colocated/public/images/1_thumb.jpg -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-colocated/public/images/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth-colocated/public/images/2.jpg -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-colocated/public/images/2_thumb.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth-colocated/public/images/2_thumb.jpg -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-colocated/public/images/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth-colocated/public/images/3.jpg -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-colocated/public/images/3_thumb.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth-colocated/public/images/3_thumb.jpg -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-colocated/public/images/4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth-colocated/public/images/4.jpg -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-colocated/public/images/4_thumb.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth-colocated/public/images/4_thumb.jpg -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-colocated/public/images/5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth-colocated/public/images/5.jpg -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-colocated/public/images/5_thumb.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth-colocated/public/images/5_thumb.jpg -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-colocated/public/images/6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth-colocated/public/images/6.jpg -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-colocated/public/images/6_thumb.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth-colocated/public/images/6_thumb.jpg -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-colocated/public/images/7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth-colocated/public/images/7.jpg -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-colocated/public/images/7_thumb.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth-colocated/public/images/7_thumb.jpg -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-colocated/public/images/8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth-colocated/public/images/8.jpg -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-colocated/public/images/8_thumb.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth-colocated/public/images/8_thumb.jpg -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-colocated/public/images/9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth-colocated/public/images/9.jpg -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-colocated/public/images/9_thumb.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth-colocated/public/images/9_thumb.jpg -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-colocated/public/images/about.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth-colocated/public/images/about.jpg -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-colocated/public/images/author.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth-colocated/public/images/author.jpg -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-colocated/public/images/avatar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth-colocated/public/images/avatar.png -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-colocated/public/images/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth-colocated/public/images/favicon.png -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-colocated/public/images/feature1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth-colocated/public/images/feature1.png -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-colocated/public/images/feature2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth-colocated/public/images/feature2.png -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-colocated/public/images/feature3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth-colocated/public/images/feature3.png -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-colocated/public/images/hero.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth-colocated/public/images/hero.png -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-colocated/public/images/intro.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth-colocated/public/images/intro.jpg -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-colocated/public/images/review1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth-colocated/public/images/review1.jpg -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-colocated/public/images/review2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth-colocated/public/images/review2.jpg -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-colocated/public/images/review3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth-colocated/public/images/review3.jpg -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-colocated/public/js/init.js: -------------------------------------------------------------------------------- 1 | window.onNextjsAppDidMount = function() { 2 | // Sticky header 3 | var offsetY = 0; 4 | var ticking = false; 5 | 6 | window.addEventListener('scroll', function (e) { 7 | offsetY = window.scrollY; 8 | if (!ticking) { 9 | window.requestAnimationFrame(function () { 10 | handleHeader(offsetY); 11 | ticking = false; 12 | }); 13 | ticking = true; 14 | } 15 | }); 16 | 17 | function handleHeader(scrollPos) { 18 | if (scrollPos > 0) { 19 | document.body.classList.add('has--scrolled'); 20 | } else { 21 | document.body.classList.remove('has--scrolled'); 22 | } 23 | } 24 | 25 | }; -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-colocated/src/components/ActionLink.tsx: -------------------------------------------------------------------------------- 1 | import type { FC } from 'react' 2 | import React from 'react' 3 | 4 | import { Link, withPrefix } from '../utils' 5 | import type * as types from 'contentlayer/generated' 6 | 7 | export const ActionLink: FC<{ action: types.Action }> = ({ action }) => ( 8 | 13 | {action.label} 14 | 15 | ) 16 | -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-colocated/src/components/footer/FooterNav.tsx: -------------------------------------------------------------------------------- 1 | import type { FC } from 'react' 2 | import React from 'react' 3 | 4 | import { Action } from '../Action' 5 | import type * as types from 'contentlayer/generated' 6 | 7 | export const FooterNav: FC<{ section: types.FooterNav }> = ({ section }) => ( 8 |
9 | {section.title &&

{section.title}

} 10 | {section.nav_links && ( 11 |
    12 | {section.nav_links.map((action, action_idx) => ( 13 |
  • 14 | 15 |
  • 16 | ))} 17 |
18 | )} 19 |
20 | ) 21 | -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-colocated/src/components/footer/FooterText.tsx: -------------------------------------------------------------------------------- 1 | import type { FC } from 'react' 2 | import React from 'react' 3 | 4 | import { Link, markdownify, withPrefix } from '../../utils' 5 | import type * as types from 'contentlayer/generated' 6 | 7 | export const FooterText: FC<{ section: types.FooterText }> = ({ section }) => ( 8 |
9 | {section.image && 10 | (section.image_url ? ( 11 | 12 | {section.image_alt} 13 | 14 | ) : ( 15 |

16 | {section.image_alt} 17 |

18 | ))} 19 | {section.title &&

{section.title}

} 20 | {markdownify(section.content)} 21 |
22 | ) 23 | -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-colocated/src/components/landing-sections/CtaButtons.tsx: -------------------------------------------------------------------------------- 1 | import type { FC } from 'react' 2 | import React from 'react' 3 | 4 | import { Action } from '../Action' 5 | import type * as types from 'contentlayer/generated' 6 | 7 | export const CtaButtons: FC<{ actions: types.Action[] }> = ({ actions }) => ( 8 | <> 9 | {actions.map((action, index) => ( 10 | 11 | ))} 12 | 13 | ) 14 | -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-colocated/src/components/landing-sections/model.ts: -------------------------------------------------------------------------------- 1 | export const sectionBaseFields = { 2 | section_id: { 3 | type: 'string', 4 | label: 'Section ID', 5 | description: 'A unique identifier of the section, must not contain whitespace', 6 | }, 7 | title: { 8 | type: 'string', 9 | label: 'Title', 10 | description: 'The title of the section', 11 | }, 12 | type: { 13 | type: 'string', 14 | label: 'Section type', 15 | required: true, 16 | description: 'Needed for contentlayer for polymorphic list types', 17 | }, 18 | } as const 19 | -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-colocated/src/contentlayer/documents/Person.ts: -------------------------------------------------------------------------------- 1 | import { defineDocument } from 'contentlayer/source-files/schema' 2 | 3 | export const Person = defineDocument(() => ({ 4 | name: 'Person', 5 | filePathPattern: 'data/authors/*.yaml', 6 | fileType: 'yaml', 7 | fields: { 8 | first_name: { type: 'string' }, 9 | last_name: { type: 'string' }, 10 | bio: { type: 'markdown' }, 11 | photo: { type: 'image' }, 12 | }, 13 | })) 14 | -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-colocated/src/contentlayer/index.ts: -------------------------------------------------------------------------------- 1 | export { Config } from './documents/Config' 2 | export { LandingModel } from '../layouts/LandingLayout' 3 | export { BlogModel } from '../layouts/BlogLayout' 4 | export { PageModel } from '../layouts/PageLayout' 5 | export { PostModel } from '../layouts/PostLayout' 6 | export { Person } from './documents/Person' 7 | -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-colocated/src/pages/_app.tsx: -------------------------------------------------------------------------------- 1 | import '../sass/main.scss' 2 | 3 | import type { AppProps } from 'next/app' 4 | import React from 'react' 5 | 6 | export default function MyApp({ Component, pageProps }: AppProps) { 7 | return 8 | } 9 | -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-colocated/src/sass/imports/_banner.scss: -------------------------------------------------------------------------------- 1 | body.has-theme-bar { 2 | #page { 3 | top: 60px; 4 | 5 | .site-header { 6 | @media only screen and (min-width: 801px) { 7 | top: 60px; 8 | } 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-colocated/src/sass/imports/_functions.scss: -------------------------------------------------------------------------------- 1 | // Gets a value from a map. 2 | @function map-deep-get($map, $keys...) { 3 | @each $key in $keys { 4 | $map: map-get($map, $key); 5 | } 6 | @return $map; 7 | } -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-colocated/src/sass/imports/_menus.scss: -------------------------------------------------------------------------------- 1 | .menu { 2 | list-style: none; 3 | margin: 0; 4 | padding: 0; 5 | } 6 | 7 | .menu-item { 8 | font-size: 0.88889rem; 9 | line-height: 1.5; 10 | } 11 | -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-colocated/src/sass/main.scss: -------------------------------------------------------------------------------- 1 | @import "imports/functions"; 2 | @import "imports/variables"; 3 | @import "imports/reset"; 4 | @import "imports/general"; 5 | @import "imports/helpers"; 6 | @import "imports/tables"; 7 | @import "imports/forms"; 8 | @import "imports/buttons"; 9 | @import "imports/icons"; 10 | @import "imports/menus"; 11 | @import "imports/structure"; 12 | @import "imports/header"; 13 | @import "imports/posts"; 14 | @import "imports/sections"; 15 | @import "imports/footer"; 16 | @import "imports/palettes"; 17 | @import "imports/banner"; 18 | -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-colocated/src/utils/classNames.tsx: -------------------------------------------------------------------------------- 1 | import classnames from 'classnames' 2 | 3 | // A simple wrapper around classNames to return null, if no classes were generated 4 | // Otherwise, original classNames returns empty string which causes class="" to be generated 5 | export default function classNames(...args: any[]) { 6 | return classnames(...args) || undefined 7 | } 8 | -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-colocated/src/utils/contentlayer.ts: -------------------------------------------------------------------------------- 1 | import type { DocumentGen } from 'contentlayer/core' 2 | 3 | export const urlFromFilePath = (doc: DocumentGen): string => doc._raw.flattenedPath.replace(/pages\/?/, '') 4 | -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-colocated/src/utils/index.ts: -------------------------------------------------------------------------------- 1 | export { default as classNames } from './classNames' 2 | export { default as htmlToReact } from './htmlToReact' 3 | export { default as Link } from './link' 4 | export { default as markdownify } from './markdownify' 5 | export { default as withPrefix } from './withPrefix' 6 | -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-colocated/src/utils/link.tsx: -------------------------------------------------------------------------------- 1 | import NextLink from 'next/link' 2 | import type { FC, HTMLProps } from 'react' 3 | import React from 'react' 4 | 5 | const Link: FC> = ({ children, href, ...props }) => { 6 | // Pass Any internal link to Next.js Link, for anything else, use tag 7 | const internal = /^\/(?!\/)/.test(href ?? '') 8 | 9 | if (internal) { 10 | // For root page, use index.js, for rest use [...slug].js 11 | const page = href === '/' ? '/' : '/[...slug]' 12 | return ( 13 | 14 | {children} 15 | 16 | ) 17 | } 18 | 19 | return ( 20 | 21 | {children} 22 | 23 | ) 24 | } 25 | 26 | export default Link 27 | -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-colocated/src/utils/markdownify.tsx: -------------------------------------------------------------------------------- 1 | // export default function markdownify(markdown) { 2 | // if (!markdown) { 3 | // return null; 4 | // } 5 | // return htmlToReact(marked(markdown)); 6 | // }; 7 | 8 | export default function markdownify(markdown) { 9 | if (!markdown) { 10 | return null 11 | } 12 | return
13 | } 14 | -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-colocated/src/utils/next.ts: -------------------------------------------------------------------------------- 1 | import type { GetServerSideProps, GetStaticPaths, GetStaticProps } from 'next' 2 | 3 | /** Needed in combination with `InferGetServerSidePropsType` */ 4 | export function defineServerSideProps(fn: Fn): Fn { 5 | return fn 6 | } 7 | 8 | /** Needed in combination with `InferGetStaticPropsType` */ 9 | export function defineStaticProps(fn: Fn): Fn { 10 | return fn 11 | } 12 | 13 | export function defineStaticPaths(fn: Fn): Fn { 14 | return fn 15 | } 16 | 17 | export function toParams(path: string): { params: { slug: string[] } } { 18 | return { params: { slug: path.replace(/^\//, '').split('/') } } 19 | } 20 | 21 | export function notUndefined(_: T | undefined): _ is T { 22 | return _ !== undefined 23 | } 24 | -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-colocated/src/utils/withPrefix.ts: -------------------------------------------------------------------------------- 1 | import _ from 'lodash' 2 | 3 | export default function withPrefix(url: string | undefined, pathPrefix: string = '/'): string | undefined { 4 | if (!url) { 5 | return url 6 | } 7 | 8 | if (_.startsWith(url, '#') || _.startsWith(url, 'http://') || _.startsWith(url, 'https://')) { 9 | return url 10 | } 11 | 12 | const basePath = _.trim(pathPrefix, '/') 13 | return '/' + _.compact([basePath, _.trimStart(url, '/')]).join('/') 14 | } 15 | -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-colocated/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "jsx": "preserve", 4 | "allowSyntheticDefaultImports": true, 5 | "rootDir": ".", 6 | "allowJs": true, 7 | "skipLibCheck": true, 8 | "forceConsistentCasingInFileNames": true, 9 | "esModuleInterop": true, 10 | "resolveJsonModule": true, 11 | "incremental": false, 12 | "composite": false, 13 | "noEmit": true, 14 | "target": "es5", 15 | "lib": ["dom", "dom.iterable", "esnext"], 16 | "strict": false, 17 | "module": "esnext", 18 | "moduleResolution": "node", 19 | "isolatedModules": true 20 | }, 21 | "include": ["next-env.d.ts", "**/*.tsx", "**/*.ts", "./node_modules/.contentlayer/*", "./node_modules/@types"], 22 | "exclude": ["node_modules"] 23 | } 24 | -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-contentful/contentlayer-stackbit-yaml-generator.js: -------------------------------------------------------------------------------- 1 | const { defineTransform } = require('contentlayer-stackbit-yaml-generator') 2 | 3 | module.exports = defineTransform((config) => { 4 | config.pagesDir = 'content/pages' 5 | config.dataDir = 'content/data' 6 | 7 | config.models['Person'].folder = 'authors' 8 | config.models['Blog'].file = 'blog.md' 9 | config.models['Config'].file = 'config.json' 10 | config.models['Page'].match = ['about.md', 'privacy-policy.md', 'signup.md', 'style-guide.md', 'terms-of-service.md'] 11 | config.models['Post'].match = 'blog/**.md' 12 | config.models['Landing'].match = ['contact.md', 'features.md', 'index.md', 'pricing.md'] 13 | 14 | return config 15 | }) 16 | -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-contentful/copy-code.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | rm -rf ./src/{components,layouts,sass,utils,pages} ./public/ 4 | 5 | cp -r ../playground-azimuth/src/{components,layouts,sass,utils,pages} ./src/ 6 | cp -r ../playground-azimuth/public ./ 7 | cp -r ../playground-azimuth/next-env.d.ts ./ -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-contentful/next-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | /// 4 | 5 | // NOTE: This file should not be edited 6 | // see https://nextjs.org/docs/basic-features/typescript for more information. 7 | -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-contentful/next.config.js: -------------------------------------------------------------------------------- 1 | const { withContentlayer } = require('next-contentlayer') 2 | 3 | module.exports = withContentlayer({}) 4 | -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-contentful/public/images/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth-contentful/public/images/1.jpg -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-contentful/public/images/10.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth-contentful/public/images/10.jpg -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-contentful/public/images/10_thumb.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth-contentful/public/images/10_thumb.jpg -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-contentful/public/images/11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth-contentful/public/images/11.jpg -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-contentful/public/images/11_thumb.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth-contentful/public/images/11_thumb.jpg -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-contentful/public/images/12.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth-contentful/public/images/12.jpg -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-contentful/public/images/12_thumb.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth-contentful/public/images/12_thumb.jpg -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-contentful/public/images/1_thumb.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth-contentful/public/images/1_thumb.jpg -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-contentful/public/images/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth-contentful/public/images/2.jpg -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-contentful/public/images/2_thumb.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth-contentful/public/images/2_thumb.jpg -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-contentful/public/images/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth-contentful/public/images/3.jpg -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-contentful/public/images/3_thumb.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth-contentful/public/images/3_thumb.jpg -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-contentful/public/images/4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth-contentful/public/images/4.jpg -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-contentful/public/images/4_thumb.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth-contentful/public/images/4_thumb.jpg -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-contentful/public/images/5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth-contentful/public/images/5.jpg -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-contentful/public/images/5_thumb.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth-contentful/public/images/5_thumb.jpg -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-contentful/public/images/6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth-contentful/public/images/6.jpg -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-contentful/public/images/6_thumb.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth-contentful/public/images/6_thumb.jpg -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-contentful/public/images/7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth-contentful/public/images/7.jpg -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-contentful/public/images/7_thumb.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth-contentful/public/images/7_thumb.jpg -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-contentful/public/images/8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth-contentful/public/images/8.jpg -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-contentful/public/images/8_thumb.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth-contentful/public/images/8_thumb.jpg -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-contentful/public/images/9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth-contentful/public/images/9.jpg -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-contentful/public/images/9_thumb.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth-contentful/public/images/9_thumb.jpg -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-contentful/public/images/about.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth-contentful/public/images/about.jpg -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-contentful/public/images/author.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth-contentful/public/images/author.jpg -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-contentful/public/images/avatar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth-contentful/public/images/avatar.png -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-contentful/public/images/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth-contentful/public/images/favicon.png -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-contentful/public/images/feature1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth-contentful/public/images/feature1.png -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-contentful/public/images/feature2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth-contentful/public/images/feature2.png -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-contentful/public/images/feature3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth-contentful/public/images/feature3.png -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-contentful/public/images/hero.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth-contentful/public/images/hero.png -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-contentful/public/images/intro.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth-contentful/public/images/intro.jpg -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-contentful/public/images/review1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth-contentful/public/images/review1.jpg -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-contentful/public/images/review2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth-contentful/public/images/review2.jpg -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-contentful/public/images/review3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth-contentful/public/images/review3.jpg -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-contentful/public/js/init.js: -------------------------------------------------------------------------------- 1 | window.onNextjsAppDidMount = function() { 2 | // Sticky header 3 | var offsetY = 0; 4 | var ticking = false; 5 | 6 | window.addEventListener('scroll', function (e) { 7 | offsetY = window.scrollY; 8 | if (!ticking) { 9 | window.requestAnimationFrame(function () { 10 | handleHeader(offsetY); 11 | ticking = false; 12 | }); 13 | ticking = true; 14 | } 15 | }); 16 | 17 | function handleHeader(scrollPos) { 18 | if (scrollPos > 0) { 19 | document.body.classList.add('has--scrolled'); 20 | } else { 21 | document.body.classList.remove('has--scrolled'); 22 | } 23 | } 24 | 25 | }; -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-contentful/src/components/ActionLink.tsx: -------------------------------------------------------------------------------- 1 | import type { FC } from 'react' 2 | import React from 'react' 3 | 4 | import { Link, withPrefix } from '../utils' 5 | import type { Action } from 'contentlayer/generated' 6 | 7 | export const ActionLink: FC<{ action: Action }> = ({ action }) => ( 8 | 13 | {action.label} 14 | 15 | ) 16 | -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-contentful/src/components/footer/FooterNav.tsx: -------------------------------------------------------------------------------- 1 | import type { FC } from 'react' 2 | import React from 'react' 3 | 4 | import { Action } from '../Action' 5 | import type { Footer_nav } from 'contentlayer/generated' 6 | 7 | export const FooterNav: FC<{ section: Footer_nav }> = ({ section }) => ( 8 |
9 | {section.title &&

{section.title}

} 10 | {section.nav_links && ( 11 |
    12 | {section.nav_links.map((action, action_idx) => ( 13 |
  • 14 | 15 |
  • 16 | ))} 17 |
18 | )} 19 |
20 | ) 21 | -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-contentful/src/components/footer/FooterText.tsx: -------------------------------------------------------------------------------- 1 | import type { FC } from 'react' 2 | import React from 'react' 3 | 4 | import { Link, markdownify, withPrefix } from '../../utils' 5 | import type { Footer_text } from 'contentlayer/generated' 6 | 7 | export const FooterText: FC<{ section: Footer_text }> = ({ section }) => ( 8 |
9 | {section.image && 10 | (section.image_url ? ( 11 | 12 | {section.image_alt} 13 | 14 | ) : ( 15 |

16 | {section.image_alt} 17 |

18 | ))} 19 | {section.title &&

{section.title}

} 20 | {markdownify(section.content)} 21 |
22 | ) 23 | -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-contentful/src/components/landing-sections/CtaButtons.tsx: -------------------------------------------------------------------------------- 1 | import type { FC } from 'react' 2 | import React from 'react' 3 | 4 | import { Action } from '../Action' 5 | import type { Action as Action_ } from 'contentlayer/generated' 6 | 7 | export const CtaButtons: FC<{ actions: Action_[] }> = ({ actions }) => ( 8 | <> 9 | {actions.map((action, index) => ( 10 | 11 | ))} 12 | 13 | ) 14 | -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-contentful/src/pages/_app.tsx: -------------------------------------------------------------------------------- 1 | import '../sass/main.scss' 2 | 3 | import type { AppProps } from 'next/app' 4 | import React from 'react' 5 | 6 | export default function MyApp({ Component, pageProps }: AppProps) { 7 | return 8 | } 9 | -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-contentful/src/sass/imports/_banner.scss: -------------------------------------------------------------------------------- 1 | body.has-theme-bar { 2 | #page { 3 | top: 60px; 4 | 5 | .site-header { 6 | @media only screen and (min-width: 801px) { 7 | top: 60px; 8 | } 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-contentful/src/sass/imports/_functions.scss: -------------------------------------------------------------------------------- 1 | // Gets a value from a map. 2 | @function map-deep-get($map, $keys...) { 3 | @each $key in $keys { 4 | $map: map-get($map, $key); 5 | } 6 | @return $map; 7 | } -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-contentful/src/sass/imports/_menus.scss: -------------------------------------------------------------------------------- 1 | .menu { 2 | list-style: none; 3 | margin: 0; 4 | padding: 0; 5 | } 6 | 7 | .menu-item { 8 | font-size: 0.88889rem; 9 | line-height: 1.5; 10 | } 11 | -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-contentful/src/sass/main.scss: -------------------------------------------------------------------------------- 1 | @import "imports/functions"; 2 | @import "imports/variables"; 3 | @import "imports/reset"; 4 | @import "imports/general"; 5 | @import "imports/helpers"; 6 | @import "imports/tables"; 7 | @import "imports/forms"; 8 | @import "imports/buttons"; 9 | @import "imports/icons"; 10 | @import "imports/menus"; 11 | @import "imports/structure"; 12 | @import "imports/header"; 13 | @import "imports/posts"; 14 | @import "imports/sections"; 15 | @import "imports/footer"; 16 | @import "imports/palettes"; 17 | @import "imports/banner"; 18 | -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-contentful/src/utils/classNames.tsx: -------------------------------------------------------------------------------- 1 | import classnames from 'classnames' 2 | 3 | // A simple wrapper around classNames to return null, if no classes were generated 4 | // Otherwise, original classNames returns empty string which causes class="" to be generated 5 | export default function classNames(...args: any[]) { 6 | return classnames(...args) || undefined 7 | } 8 | -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-contentful/src/utils/index.ts: -------------------------------------------------------------------------------- 1 | export { default as classNames } from './classNames' 2 | export { default as htmlToReact } from './htmlToReact' 3 | export { default as Link } from './link' 4 | export { default as markdownify } from './markdownify' 5 | export { default as withPrefix } from './withPrefix' 6 | -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-contentful/src/utils/link.tsx: -------------------------------------------------------------------------------- 1 | import NextLink from 'next/link' 2 | import React, { FC, HTMLProps } from 'react' 3 | 4 | const Link: FC> = ({ children, href, ...props }) => { 5 | // Pass Any internal link to Next.js Link, for anything else, use tag 6 | const internal = /^\/(?!\/)/.test(href ?? '') 7 | 8 | if (internal) { 9 | // For root page, use index.js, for rest use [...slug].js 10 | const page = href === '/' ? '/' : '/[...slug]' 11 | return ( 12 | 13 | {children} 14 | 15 | ) 16 | } 17 | 18 | return ( 19 | 20 | {children} 21 | 22 | ) 23 | } 24 | 25 | export default Link 26 | -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-contentful/src/utils/markdownify.js: -------------------------------------------------------------------------------- 1 | // export default function markdownify(markdown) { 2 | // if (!markdown) { 3 | // return null; 4 | // } 5 | // return htmlToReact(marked(markdown)); 6 | // }; 7 | 8 | export default function markdownify(markdown) { 9 | if (!markdown) { 10 | return null 11 | } 12 | return
13 | } 14 | -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-contentful/src/utils/next.ts: -------------------------------------------------------------------------------- 1 | import type { GetServerSideProps, GetStaticPaths, GetStaticProps } from 'next' 2 | 3 | /** Needed in combination with `InferGetServerSidePropsType` */ 4 | export function defineServerSideProps(fn: Fn): Fn { 5 | return fn 6 | } 7 | 8 | /** Needed in combination with `InferGetStaticPropsType` */ 9 | export function defineStaticProps(fn: Fn): Fn { 10 | return fn 11 | } 12 | 13 | export function defineStaticPaths(fn: Fn): Fn { 14 | return fn 15 | } 16 | 17 | export function toParams(path: string): { params: { slug: string[] } } { 18 | return { params: { slug: path.replace(/^\//, '').split('/') } } 19 | } 20 | 21 | export function notUndefined(_: T | undefined): _ is T { 22 | return _ !== undefined 23 | } 24 | -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-contentful/src/utils/withPrefix.ts: -------------------------------------------------------------------------------- 1 | import _ from 'lodash' 2 | 3 | export default function withPrefix(url: string | undefined, pathPrefix: string = '/'): string | undefined { 4 | if (!url) { 5 | return url 6 | } 7 | 8 | if (_.startsWith(url, '#') || _.startsWith(url, 'http://') || _.startsWith(url, 'https://')) { 9 | return url 10 | } 11 | 12 | const basePath = _.trim(pathPrefix, '/') 13 | return '/' + _.compact([basePath, _.trimStart(url, '/')]).join('/') 14 | } 15 | -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-contentful/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "jsx": "preserve", 4 | "allowSyntheticDefaultImports": true, 5 | "rootDir": ".", 6 | "allowJs": true, 7 | "skipLibCheck": true, 8 | "forceConsistentCasingInFileNames": true, 9 | "esModuleInterop": true, 10 | "resolveJsonModule": true, 11 | "incremental": false, 12 | "composite": false, 13 | "noEmit": true, 14 | "target": "es5", 15 | "lib": ["dom", "dom.iterable", "esnext"], 16 | "strict": false, 17 | "module": "esnext", 18 | "moduleResolution": "node", 19 | "isolatedModules": true 20 | }, 21 | "include": ["next-env.d.ts", "**/*.tsx", "**/*.ts", "./node_modules/.contentlayer/*", "./node_modules/@types"], 22 | "exclude": ["node_modules"] 23 | } 24 | -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-sanity/.gitignore: -------------------------------------------------------------------------------- 1 | web/src/components 2 | web/src/layouts 3 | web/src/sass 4 | web/src/utils 5 | web/src/pages 6 | web/public 7 | web/next-env.d.ts -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-sanity/copy-code.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | rm -rf ./web/src/{components,layouts,sass,utils,pages} ./web/public/ 4 | 5 | cp -r ../playground-azimuth/src/{components,layouts,sass,utils,pages} ./web/src/ 6 | cp -r ../playground-azimuth/public ./web/ 7 | cp -r ../playground-azimuth/next-env.d.ts ./web/ -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-sanity/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "example-azimuth-sanity-monorepo", 3 | "private": true, 4 | "workspaces": [ 5 | "./web", 6 | "./studio" 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-sanity/studio/.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | /dist 3 | -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-sanity/studio/README.md: -------------------------------------------------------------------------------- 1 | # Sanity Clean Content Studio 2 | 3 | Congratulations, you have now installed the Sanity Content Studio, an open source real-time content editing environment connected to the Sanity backend. 4 | 5 | Now you can do the following things: 6 | 7 | - [Read “getting started” in the docs](https://www.sanity.io/docs/introduction/getting-started?utm_source=readme) 8 | - [Join the community Slack](https://slack.sanity.io/?utm_source=readme) 9 | - [Extend and build plugins](https://www.sanity.io/docs/content-studio/extending?utm_source=readme) 10 | -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-sanity/studio/config/.checksums: -------------------------------------------------------------------------------- 1 | { 2 | "#": "Used by Sanity to keep track of configuration file checksums, do not delete or modify!", 3 | "@sanity/default-layout": "bb034f391ba508a6ca8cd971967cbedeb131c4d19b17b28a0895f32db5d568ea", 4 | "@sanity/default-login": "6fb6d3800aa71346e1b84d95bbcaa287879456f2922372bb0294e30b968cd37f", 5 | "@sanity/form-builder": "b38478227ba5e22c91981da4b53436df22e48ff25238a55a973ed620be5068aa", 6 | "@sanity/data-aspects": "d199e2c199b3e26cd28b68dc84d7fc01c9186bf5089580f2e2446994d36b3cb6" 7 | } 8 | -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-sanity/studio/config/@sanity/data-aspects.json: -------------------------------------------------------------------------------- 1 | { 2 | "listOptions": {} 3 | } 4 | -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-sanity/studio/config/@sanity/default-layout.json: -------------------------------------------------------------------------------- 1 | { 2 | "toolSwitcher": { 3 | "order": [], 4 | "hidden": [] 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-sanity/studio/config/@sanity/default-login.json: -------------------------------------------------------------------------------- 1 | { 2 | "providers": { 3 | "mode": "append", 4 | "redirectOnSingle": false, 5 | "entries": [] 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-sanity/studio/config/@sanity/form-builder.json: -------------------------------------------------------------------------------- 1 | { 2 | "images": { 3 | "directUploads": true 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-sanity/studio/deskStructure.js: -------------------------------------------------------------------------------- 1 | import S from '@sanity/desk-tool/structure-builder' 2 | 3 | export default () => 4 | S.list() 5 | .title('Content') 6 | .items([ 7 | S.listItem().title('Site Settings').child(S.document().schemaType('config').documentId('config')), 8 | S.divider(), 9 | ...S.documentTypeListItems().filter((item) => !['config'].includes(item.getId())), 10 | ]) 11 | -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-sanity/studio/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "playground-azimuth-sanity-studio", 3 | "private": true, 4 | "version": "1.0.0", 5 | "scripts": { 6 | "start": "sanity start --host=0.0.0.0", 7 | "build": "sanity build", 8 | "deploy": "sanity deploy", 9 | "clean": "rm -rf node_modules && rm -rf dist" 10 | }, 11 | "dependencies": { 12 | "@sanity/base": "^2.10.5", 13 | "@sanity/color-input": "^2.2.6", 14 | "@sanity/components": "^2.2.6", 15 | "@sanity/core": "^2.10.5", 16 | "@sanity/default-layout": "^2.10.5", 17 | "@sanity/default-login": "^2.10.5", 18 | "@sanity/desk-tool": "^2.10.5", 19 | "@sanity/vision": "^2.10.5", 20 | "prop-types": "^15.8.1", 21 | "react": "^18.2.0", 22 | "react-dom": "^18.2.0", 23 | "sanity-plugin-markdown": "^1.0.1" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-sanity/studio/plugins/.gitkeep: -------------------------------------------------------------------------------- 1 | User-specific packages can be placed here 2 | -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-sanity/studio/sanity.json: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "project": { 4 | "name": "azimuth-nextjs-sanity" 5 | }, 6 | "api": { 7 | "projectId": "vqr9ere3", 8 | "dataset": "production" 9 | }, 10 | "plugins": [ 11 | "@sanity/base", 12 | "@sanity/components", 13 | "@sanity/default-layout", 14 | "@sanity/default-login", 15 | "@sanity/desk-tool", 16 | "@sanity/color-input", 17 | "markdown" 18 | ], 19 | "env": { 20 | "development": { 21 | "plugins": ["@sanity/vision"] 22 | } 23 | }, 24 | "parts": [ 25 | { 26 | "name": "part:@sanity/base/schema", 27 | "path": "./schemas/schema.js" 28 | }, 29 | { 30 | "name": "part:@sanity/desk-tool/structure", 31 | "path": "./deskStructure.js" 32 | } 33 | ] 34 | } 35 | -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-sanity/studio/schemas/blog.js: -------------------------------------------------------------------------------- 1 | export default { 2 | type: 'document', 3 | name: 'blog', 4 | title: 'Blog', 5 | fields: [ 6 | { 7 | type: 'string', 8 | name: 'title', 9 | title: 'Title', 10 | description: 'The title of the page', 11 | validation: (Rule) => Rule.required(), 12 | }, 13 | { 14 | type: 'string', 15 | name: 'url_path', 16 | title: 'URL Path', 17 | description: 18 | 'The URL path of this page relative to site root. For example, the site root page would be "/", and post page would be "posts/new-post/"', 19 | validation: (Rule) => Rule.required(), 20 | }, 21 | { 22 | type: 'seo', 23 | name: 'seo', 24 | title: 'Seo', 25 | validation: null, 26 | }, 27 | ], 28 | singleInstance: true, 29 | preview: { 30 | select: { 31 | title: 'title', 32 | }, 33 | }, 34 | } 35 | -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-sanity/studio/schemas/faq_item.js: -------------------------------------------------------------------------------- 1 | export default { 2 | type: 'object', 3 | name: 'faq_item', 4 | title: 'FAQ Item', 5 | fields: [ 6 | { 7 | type: 'text', 8 | name: 'question', 9 | title: 'Question', 10 | validation: null, 11 | }, 12 | { 13 | type: 'markdown', 14 | name: 'answer', 15 | title: 'Answer', 16 | validation: null, 17 | }, 18 | ], 19 | preview: { 20 | select: { 21 | title: 'type', 22 | }, 23 | }, 24 | } 25 | -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-sanity/studio/schemas/footer_nav.js: -------------------------------------------------------------------------------- 1 | export default { 2 | type: 'object', 3 | name: 'footer_nav', 4 | title: 'Vertical Navigation', 5 | fields: [ 6 | { 7 | type: 'string', 8 | name: 'title', 9 | title: 'Title', 10 | description: 'The title of the section', 11 | validation: null, 12 | }, 13 | { 14 | type: 'array', 15 | name: 'nav_links', 16 | title: 'Vertical Navigation Links', 17 | description: 'List of vertical navigation links', 18 | validation: null, 19 | of: [ 20 | { 21 | type: 'action', 22 | }, 23 | ], 24 | }, 25 | ], 26 | preview: { 27 | select: { 28 | title: 'title', 29 | }, 30 | }, 31 | } 32 | -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-sanity/studio/schemas/person.js: -------------------------------------------------------------------------------- 1 | export default { 2 | type: 'document', 3 | name: 'person', 4 | title: 'Person', 5 | fields: [ 6 | { 7 | type: 'string', 8 | name: 'first_name', 9 | title: 'First Name', 10 | validation: null, 11 | }, 12 | { 13 | type: 'string', 14 | name: 'last_name', 15 | title: 'Last Name', 16 | validation: null, 17 | }, 18 | { 19 | type: 'markdown', 20 | name: 'bio', 21 | title: 'Bio', 22 | validation: null, 23 | }, 24 | { 25 | type: 'image', 26 | name: 'photo', 27 | title: 'Photo', 28 | validation: null, 29 | }, 30 | ], 31 | preview: { 32 | select: { 33 | title: 'first_name', 34 | }, 35 | }, 36 | } 37 | -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-sanity/studio/schemas/review_item.js: -------------------------------------------------------------------------------- 1 | export default { 2 | type: 'object', 3 | name: 'review_item', 4 | title: 'Review Item', 5 | fields: [ 6 | { 7 | type: 'string', 8 | name: 'author', 9 | title: 'Author', 10 | validation: null, 11 | }, 12 | { 13 | type: 'image', 14 | name: 'avatar', 15 | title: 'Author Image', 16 | validation: null, 17 | }, 18 | { 19 | type: 'string', 20 | name: 'avatar_alt', 21 | title: 'Author Image Alt Text', 22 | validation: null, 23 | }, 24 | { 25 | type: 'text', 26 | name: 'content', 27 | title: 'Content', 28 | validation: null, 29 | }, 30 | ], 31 | preview: { 32 | select: { 33 | title: 'author', 34 | }, 35 | }, 36 | } 37 | -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-sanity/studio/static/.gitkeep: -------------------------------------------------------------------------------- 1 | Files placed here will be served by the Sanity server under the `/static`-prefix 2 | -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-sanity/studio/static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth-sanity/studio/static/favicon.ico -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-sanity/studio/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": ["./node_modules/@sanity/base/types/**/*.ts", "./**/*.ts", "./**/*.tsx"] 3 | } 4 | -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-sanity/web/contentlayer/contentlayer.ts: -------------------------------------------------------------------------------- 1 | import { makeSourcePlugin } from '@contentlayer/source-sanity' 2 | import { defineConfig } from 'contentlayer/core' 3 | import * as path from 'path' 4 | 5 | export default defineConfig({ 6 | source: makeSourcePlugin({ 7 | studioDirPath: path.join(process.cwd(), '..', 'studio'), 8 | preview: true, 9 | }), 10 | }) 11 | -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-sanity/web/next.config.js: -------------------------------------------------------------------------------- 1 | const { withContentlayer } = require('next-contentlayer') 2 | 3 | module.exports = withContentlayer({}) 4 | -------------------------------------------------------------------------------- /examples/archive/playground-azimuth-sanity/web/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "jsx": "preserve", 5 | "allowSyntheticDefaultImports": true, 6 | "rootDir": "./", 7 | "allowJs": true, 8 | "skipLibCheck": true, 9 | "forceConsistentCasingInFileNames": true, 10 | "resolveJsonModule": true, 11 | "noEmit": true 12 | }, 13 | "include": ["./src", "./src/**/*.json", "./contentlayer", "./node_modules/@types"], 14 | "references": [{ "path": "../../../contentlayer" }, { "path": "../../../@contentlayer/source-sanity" }], 15 | "exclude": ["node_modules"] 16 | } 17 | -------------------------------------------------------------------------------- /examples/archive/playground-azimuth/content/data/authors/jane-doe.yaml: -------------------------------------------------------------------------------- 1 | first_name: Jane 2 | last_name: Doe 3 | bio: >- 4 | Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor 5 | incididunt ut labore et dolore magna aliqua. Risus nullam eget felis eget nunc 6 | lobortis. Sodales ut etiam sit amet nisl purus in mollis nunc. Enim ut tellus 7 | elementum sagittis vitae. 8 | photo: images/review2.jpg 9 | -------------------------------------------------------------------------------- /examples/archive/playground-azimuth/content/data/authors/john-doe.yaml: -------------------------------------------------------------------------------- 1 | first_name: John 2 | last_name: Doe 3 | bio: >- 4 | Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor 5 | incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis 6 | nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. 7 | photo: images/review1.jpg 8 | -------------------------------------------------------------------------------- /examples/archive/playground-azimuth/content/pages/blog.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Blog 3 | seo: 4 | title: Blog 5 | description: This is the blog page 6 | extra: 7 | - name: 'og:type' 8 | value: website 9 | keyName: property 10 | - name: 'og:title' 11 | value: Blog 12 | keyName: property 13 | - name: 'og:description' 14 | value: This is the blog page 15 | keyName: property 16 | - name: 'og:image' 17 | value: images/1.jpg 18 | keyName: property 19 | relativeUrl: true 20 | - name: 'twitter:card' 21 | value: summary_large_image 22 | - name: 'twitter:title' 23 | value: Blog 24 | - name: 'twitter:description' 25 | value: This is the blog page 26 | - name: 'twitter:image' 27 | value: images/1.jpg 28 | relativeUrl: true 29 | --- 30 | -------------------------------------------------------------------------------- /examples/archive/playground-azimuth/contentlayer.config.ts: -------------------------------------------------------------------------------- 1 | import { makeSource } from 'contentlayer/source-files' 2 | 3 | import * as documentTypes from './src/contentlayer' 4 | 5 | export default makeSource({ 6 | contentDirPath: 'content', 7 | documentTypes, 8 | extensions: { 9 | stackbit: { 10 | pagesDir: 'content/pages', 11 | dataDir: 'content/data', 12 | }, 13 | }, 14 | }) 15 | -------------------------------------------------------------------------------- /examples/archive/playground-azimuth/next-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | 4 | // NOTE: This file should not be edited 5 | // see https://nextjs.org/docs/basic-features/typescript for more information. 6 | -------------------------------------------------------------------------------- /examples/archive/playground-azimuth/next.config.js: -------------------------------------------------------------------------------- 1 | const { withContentlayer } = require('next-contentlayer') 2 | 3 | module.exports = withContentlayer({}) 4 | -------------------------------------------------------------------------------- /examples/archive/playground-azimuth/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "examples-azimuth", 3 | "private": true, 4 | "scripts": { 5 | "dev": "next dev", 6 | "build": "next build", 7 | "start": "next start" 8 | }, 9 | "dependencies": { 10 | "date-fns": "^2.29.1", 11 | "marked": "^3.0.4", 12 | "next": "^12.2.3", 13 | "react": "^18.2.0", 14 | "react-dom": "^18.2.0", 15 | "react-helmet": "^6.1.0", 16 | "react-html-parser": "^2.0.2", 17 | "react-script-tag": "^1.1.2", 18 | "sass": "^1.32.7" 19 | }, 20 | "devDependencies": { 21 | "@types/react": "^18.0.15", 22 | "@types/react-dom": "^18.0.6", 23 | "@types/react-helmet": "^6.1.5", 24 | "contentlayer": "workspace:*", 25 | "contentlayer-stackbit-yaml-generator": "workspace:*", 26 | "next-contentlayer": "workspace:*", 27 | "typescript": "^4.7.4" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /examples/archive/playground-azimuth/public/images/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth/public/images/1.jpg -------------------------------------------------------------------------------- /examples/archive/playground-azimuth/public/images/10.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth/public/images/10.jpg -------------------------------------------------------------------------------- /examples/archive/playground-azimuth/public/images/10_thumb.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth/public/images/10_thumb.jpg -------------------------------------------------------------------------------- /examples/archive/playground-azimuth/public/images/11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth/public/images/11.jpg -------------------------------------------------------------------------------- /examples/archive/playground-azimuth/public/images/11_thumb.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth/public/images/11_thumb.jpg -------------------------------------------------------------------------------- /examples/archive/playground-azimuth/public/images/12.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth/public/images/12.jpg -------------------------------------------------------------------------------- /examples/archive/playground-azimuth/public/images/12_thumb.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth/public/images/12_thumb.jpg -------------------------------------------------------------------------------- /examples/archive/playground-azimuth/public/images/1_thumb.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth/public/images/1_thumb.jpg -------------------------------------------------------------------------------- /examples/archive/playground-azimuth/public/images/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth/public/images/2.jpg -------------------------------------------------------------------------------- /examples/archive/playground-azimuth/public/images/2_thumb.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth/public/images/2_thumb.jpg -------------------------------------------------------------------------------- /examples/archive/playground-azimuth/public/images/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth/public/images/3.jpg -------------------------------------------------------------------------------- /examples/archive/playground-azimuth/public/images/3_thumb.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth/public/images/3_thumb.jpg -------------------------------------------------------------------------------- /examples/archive/playground-azimuth/public/images/4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth/public/images/4.jpg -------------------------------------------------------------------------------- /examples/archive/playground-azimuth/public/images/4_thumb.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth/public/images/4_thumb.jpg -------------------------------------------------------------------------------- /examples/archive/playground-azimuth/public/images/5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth/public/images/5.jpg -------------------------------------------------------------------------------- /examples/archive/playground-azimuth/public/images/5_thumb.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth/public/images/5_thumb.jpg -------------------------------------------------------------------------------- /examples/archive/playground-azimuth/public/images/6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth/public/images/6.jpg -------------------------------------------------------------------------------- /examples/archive/playground-azimuth/public/images/6_thumb.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth/public/images/6_thumb.jpg -------------------------------------------------------------------------------- /examples/archive/playground-azimuth/public/images/7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth/public/images/7.jpg -------------------------------------------------------------------------------- /examples/archive/playground-azimuth/public/images/7_thumb.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth/public/images/7_thumb.jpg -------------------------------------------------------------------------------- /examples/archive/playground-azimuth/public/images/8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth/public/images/8.jpg -------------------------------------------------------------------------------- /examples/archive/playground-azimuth/public/images/8_thumb.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth/public/images/8_thumb.jpg -------------------------------------------------------------------------------- /examples/archive/playground-azimuth/public/images/9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth/public/images/9.jpg -------------------------------------------------------------------------------- /examples/archive/playground-azimuth/public/images/9_thumb.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth/public/images/9_thumb.jpg -------------------------------------------------------------------------------- /examples/archive/playground-azimuth/public/images/about.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth/public/images/about.jpg -------------------------------------------------------------------------------- /examples/archive/playground-azimuth/public/images/author.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth/public/images/author.jpg -------------------------------------------------------------------------------- /examples/archive/playground-azimuth/public/images/avatar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth/public/images/avatar.png -------------------------------------------------------------------------------- /examples/archive/playground-azimuth/public/images/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth/public/images/favicon.png -------------------------------------------------------------------------------- /examples/archive/playground-azimuth/public/images/feature1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth/public/images/feature1.png -------------------------------------------------------------------------------- /examples/archive/playground-azimuth/public/images/feature2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth/public/images/feature2.png -------------------------------------------------------------------------------- /examples/archive/playground-azimuth/public/images/feature3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth/public/images/feature3.png -------------------------------------------------------------------------------- /examples/archive/playground-azimuth/public/images/hero.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth/public/images/hero.png -------------------------------------------------------------------------------- /examples/archive/playground-azimuth/public/images/intro.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth/public/images/intro.jpg -------------------------------------------------------------------------------- /examples/archive/playground-azimuth/public/images/review1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth/public/images/review1.jpg -------------------------------------------------------------------------------- /examples/archive/playground-azimuth/public/images/review2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth/public/images/review2.jpg -------------------------------------------------------------------------------- /examples/archive/playground-azimuth/public/images/review3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-azimuth/public/images/review3.jpg -------------------------------------------------------------------------------- /examples/archive/playground-azimuth/public/js/init.js: -------------------------------------------------------------------------------- 1 | window.onNextjsAppDidMount = function() { 2 | // Sticky header 3 | var offsetY = 0; 4 | var ticking = false; 5 | 6 | window.addEventListener('scroll', function (e) { 7 | offsetY = window.scrollY; 8 | if (!ticking) { 9 | window.requestAnimationFrame(function () { 10 | handleHeader(offsetY); 11 | ticking = false; 12 | }); 13 | ticking = true; 14 | } 15 | }); 16 | 17 | function handleHeader(scrollPos) { 18 | if (scrollPos > 0) { 19 | document.body.classList.add('has--scrolled'); 20 | } else { 21 | document.body.classList.remove('has--scrolled'); 22 | } 23 | } 24 | 25 | }; -------------------------------------------------------------------------------- /examples/archive/playground-azimuth/src/components/ActionLink.tsx: -------------------------------------------------------------------------------- 1 | import type { FC } from 'react' 2 | import React from 'react' 3 | 4 | import { Link, withPrefix } from '../utils' 5 | import type * as types from 'contentlayer/generated' 6 | 7 | export const ActionLink: FC<{ action: types.Action }> = ({ action }) => ( 8 | 13 | {action.label} 14 | 15 | ) 16 | -------------------------------------------------------------------------------- /examples/archive/playground-azimuth/src/components/footer/FooterNav.tsx: -------------------------------------------------------------------------------- 1 | import type { FC } from 'react' 2 | import React from 'react' 3 | 4 | import { Action } from '../Action' 5 | import type * as types from 'contentlayer/generated' 6 | 7 | export const FooterNav: FC<{ section: types.FooterNav }> = ({ section }) => ( 8 |
9 | {section.title &&

{section.title}

} 10 | {section.nav_links && ( 11 |
    12 | {section.nav_links.map((action, action_idx) => ( 13 |
  • 14 | 15 |
  • 16 | ))} 17 |
18 | )} 19 |
20 | ) 21 | -------------------------------------------------------------------------------- /examples/archive/playground-azimuth/src/components/footer/FooterText.tsx: -------------------------------------------------------------------------------- 1 | import type { FC } from 'react' 2 | import React from 'react' 3 | 4 | import { Link, markdownify, withPrefix } from '../../utils' 5 | import type * as types from 'contentlayer/generated' 6 | 7 | export const FooterText: FC<{ section: types.FooterText }> = ({ section }) => ( 8 |
9 | {section.image && 10 | (section.image_url ? ( 11 | 12 | {section.image_alt} 13 | 14 | ) : ( 15 |

16 | {section.image_alt} 17 |

18 | ))} 19 | {section.title &&

{section.title}

} 20 | {markdownify(section.content)} 21 |
22 | ) 23 | -------------------------------------------------------------------------------- /examples/archive/playground-azimuth/src/components/landing-sections/CtaButtons.tsx: -------------------------------------------------------------------------------- 1 | import type { FC } from 'react' 2 | import React from 'react' 3 | 4 | import { Action } from '../Action' 5 | import type * as types from 'contentlayer/generated' 6 | 7 | export const CtaButtons: FC<{ actions: types.Action[] }> = ({ actions }) => ( 8 | <> 9 | {actions.map((action, index) => ( 10 | 11 | ))} 12 | 13 | ) 14 | -------------------------------------------------------------------------------- /examples/archive/playground-azimuth/src/contentlayer/documents/Person.ts: -------------------------------------------------------------------------------- 1 | import { defineDocumentType } from 'contentlayer/source-files' 2 | 3 | export const Person = defineDocumentType(() => ({ 4 | name: 'Person', 5 | filePathPattern: 'data/authors/*.yaml', 6 | fields: { 7 | first_name: { type: 'string' }, 8 | last_name: { type: 'string' }, 9 | bio: { type: 'markdown' }, 10 | photo: { type: 'string' }, 11 | }, 12 | extensions: { 13 | stackbit: { folder: 'authors' }, 14 | }, 15 | })) 16 | -------------------------------------------------------------------------------- /examples/archive/playground-azimuth/src/contentlayer/index.ts: -------------------------------------------------------------------------------- 1 | export { Blog } from './documents/Blog' 2 | export { Config } from './documents/Config' 3 | export { Landing } from './documents/Landing' 4 | export { Page } from './documents/Page' 5 | export { Person } from './documents/Person' 6 | export { Post } from './documents/Post' 7 | -------------------------------------------------------------------------------- /examples/archive/playground-azimuth/src/contentlayer/utils.ts: -------------------------------------------------------------------------------- 1 | import type { DocumentGen } from 'contentlayer/core' 2 | 3 | export const urlFromFilePath = (doc: DocumentGen): string => doc._raw.flattenedPath.replace(/pages\/?/, '') 4 | -------------------------------------------------------------------------------- /examples/archive/playground-azimuth/src/pages/_app.tsx: -------------------------------------------------------------------------------- 1 | import '../sass/main.scss' 2 | 3 | import type { AppProps } from 'next/app' 4 | import React from 'react' 5 | 6 | export default function MyApp({ Component, pageProps }: AppProps) { 7 | return 8 | } 9 | -------------------------------------------------------------------------------- /examples/archive/playground-azimuth/src/sass/imports/_banner.scss: -------------------------------------------------------------------------------- 1 | body.has-theme-bar { 2 | #page { 3 | top: 60px; 4 | 5 | .site-header { 6 | @media only screen and (min-width: 801px) { 7 | top: 60px; 8 | } 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /examples/archive/playground-azimuth/src/sass/imports/_functions.scss: -------------------------------------------------------------------------------- 1 | // Gets a value from a map. 2 | @function map-deep-get($map, $keys...) { 3 | @each $key in $keys { 4 | $map: map-get($map, $key); 5 | } 6 | @return $map; 7 | } -------------------------------------------------------------------------------- /examples/archive/playground-azimuth/src/sass/imports/_menus.scss: -------------------------------------------------------------------------------- 1 | .menu { 2 | list-style: none; 3 | margin: 0; 4 | padding: 0; 5 | } 6 | 7 | .menu-item { 8 | font-size: 0.88889rem; 9 | line-height: 1.5; 10 | } 11 | -------------------------------------------------------------------------------- /examples/archive/playground-azimuth/src/sass/main.scss: -------------------------------------------------------------------------------- 1 | @import "imports/functions"; 2 | @import "imports/variables"; 3 | @import "imports/reset"; 4 | @import "imports/general"; 5 | @import "imports/helpers"; 6 | @import "imports/tables"; 7 | @import "imports/forms"; 8 | @import "imports/buttons"; 9 | @import "imports/icons"; 10 | @import "imports/menus"; 11 | @import "imports/structure"; 12 | @import "imports/header"; 13 | @import "imports/posts"; 14 | @import "imports/sections"; 15 | @import "imports/footer"; 16 | @import "imports/palettes"; 17 | @import "imports/banner"; 18 | -------------------------------------------------------------------------------- /examples/archive/playground-azimuth/src/utils/classNames.tsx: -------------------------------------------------------------------------------- 1 | import classnames from 'classnames' 2 | 3 | // A simple wrapper around classNames to return null, if no classes were generated 4 | // Otherwise, original classNames returns empty string which causes class="" to be generated 5 | export default function classNames(...args: any[]) { 6 | return classnames(...args) || undefined 7 | } 8 | -------------------------------------------------------------------------------- /examples/archive/playground-azimuth/src/utils/index.ts: -------------------------------------------------------------------------------- 1 | export { default as classNames } from './classNames' 2 | export { default as htmlToReact } from './htmlToReact' 3 | export { default as Link } from './link' 4 | export { default as markdownify } from './markdownify' 5 | export { default as withPrefix } from './withPrefix' 6 | -------------------------------------------------------------------------------- /examples/archive/playground-azimuth/src/utils/link.tsx: -------------------------------------------------------------------------------- 1 | import NextLink from 'next/link' 2 | import type { FC, HTMLProps } from 'react' 3 | import React from 'react' 4 | 5 | const Link: FC> = ({ children, href, ...props }) => { 6 | // Pass Any internal link to Next.js Link, for anything else, use tag 7 | const internal = /^\/(?!\/)/.test(href ?? '') 8 | 9 | if (internal) { 10 | // For root page, use index.js, for rest use [...slug].js 11 | const page = href === '/' ? '/' : '/[...slug]' 12 | return ( 13 | 14 | {children} 15 | 16 | ) 17 | } 18 | 19 | return ( 20 | 21 | {children} 22 | 23 | ) 24 | } 25 | 26 | export default Link 27 | -------------------------------------------------------------------------------- /examples/archive/playground-azimuth/src/utils/markdownify.js: -------------------------------------------------------------------------------- 1 | // export default function markdownify(markdown) { 2 | // if (!markdown) { 3 | // return null; 4 | // } 5 | // return htmlToReact(marked(markdown)); 6 | // }; 7 | 8 | export default function markdownify(markdown) { 9 | if (!markdown) { 10 | return null 11 | } 12 | return
13 | } 14 | -------------------------------------------------------------------------------- /examples/archive/playground-azimuth/src/utils/next.ts: -------------------------------------------------------------------------------- 1 | import type { GetServerSideProps, GetStaticPaths, GetStaticProps } from 'next' 2 | 3 | /** Needed in combination with `InferGetServerSidePropsType` */ 4 | export function defineServerSideProps(fn: Fn): Fn { 5 | return fn 6 | } 7 | 8 | /** Needed in combination with `InferGetStaticPropsType` */ 9 | export function defineStaticProps(fn: Fn): Fn { 10 | return fn 11 | } 12 | 13 | export function defineStaticPaths(fn: Fn): Fn { 14 | return fn 15 | } 16 | 17 | export function toParams(path: string): { params: { slug: string[] } } { 18 | return { params: { slug: path.replace(/^\//, '').split('/') } } 19 | } 20 | 21 | export function notUndefined(_: T | undefined): _ is T { 22 | return _ !== undefined 23 | } 24 | -------------------------------------------------------------------------------- /examples/archive/playground-azimuth/src/utils/withPrefix.ts: -------------------------------------------------------------------------------- 1 | import _ from 'lodash' 2 | 3 | export default function withPrefix(url: string | undefined, pathPrefix: string = '/'): string | undefined { 4 | if (!url) { 5 | return url 6 | } 7 | 8 | if (_.startsWith(url, '#') || _.startsWith(url, 'http://') || _.startsWith(url, 'https://')) { 9 | return url 10 | } 11 | 12 | const basePath = _.trim(pathPrefix, '/') 13 | return '/' + _.compact([basePath, _.trimStart(url, '/')]).join('/') 14 | } 15 | -------------------------------------------------------------------------------- /examples/archive/playground-azimuth/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "jsx": "preserve", 4 | "allowSyntheticDefaultImports": true, 5 | "rootDir": ".", 6 | "allowJs": true, 7 | "skipLibCheck": true, 8 | "forceConsistentCasingInFileNames": true, 9 | "esModuleInterop": true, 10 | "resolveJsonModule": true, 11 | "incremental": false, 12 | "composite": false, 13 | "noEmit": true, 14 | "target": "es5", 15 | "lib": ["dom", "dom.iterable", "esnext"], 16 | "strict": false, 17 | "module": "esnext", 18 | "moduleResolution": "node", 19 | "isolatedModules": true, 20 | "baseUrl": ".", 21 | "paths": { 22 | "contentlayer/generated": ["./.contentlayer/generated"] 23 | } 24 | }, 25 | "include": ["next-env.d.ts", "**/*.tsx", "**/*.ts", ".contentlayer/generated"], 26 | "exclude": ["node_modules"] 27 | } 28 | -------------------------------------------------------------------------------- /examples/archive/playground-contentful-starter/.gitignore: -------------------------------------------------------------------------------- 1 | .next 2 | node_modules 3 | 4 | # Contentlayer 5 | .contentlayer 6 | -------------------------------------------------------------------------------- /examples/archive/playground-contentful-starter/.gitpod.yml: -------------------------------------------------------------------------------- 1 | tasks: 2 | - init: yarn 3 | command: yarn dev 4 | -------------------------------------------------------------------------------- /examples/archive/playground-contentful-starter/README.md: -------------------------------------------------------------------------------- 1 | This is a starter template for [Learn Next.js](https://nextjs.org/learn). 2 | 3 | [![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/#/https://github.com/schickling-test/contentlayer-blog) [![Edit in Stackbit](https://assets.stackbit.com/badge/create-with-stackbit.svg)](https://app.stackbit.com/create?theme=https://github.com/schickling-test/contentlayer-blog) 4 | 5 | ![](https://i.imgur.com/Lac2XLB.png) 6 | -------------------------------------------------------------------------------- /examples/archive/playground-contentful-starter/components/date.tsx: -------------------------------------------------------------------------------- 1 | import { format, parseISO } from 'date-fns' 2 | import type { FC } from 'react' 3 | 4 | export const FormattedDate: FC<{ dateString: string }> = ({ dateString }) => { 5 | const date = parseISO(dateString) 6 | return 7 | } 8 | -------------------------------------------------------------------------------- /examples/archive/playground-contentful-starter/components/layout.module.css: -------------------------------------------------------------------------------- 1 | .container { 2 | max-width: 36rem; 3 | padding: 0 1rem; 4 | margin: 3rem auto 6rem; 5 | } 6 | 7 | .header { 8 | display: flex; 9 | flex-direction: column; 10 | align-items: center; 11 | } 12 | 13 | .backToHome { 14 | margin: 3rem 0 0; 15 | } 16 | -------------------------------------------------------------------------------- /examples/archive/playground-contentful-starter/contentlayer.config.ts: -------------------------------------------------------------------------------- 1 | import { makeSourcePlugin } from '@contentlayer/source-contentful' 2 | 3 | export default makeSourcePlugin({ 4 | accessToken: process.env['CONTENTFUL_ACCESS_TOKEN']!, 5 | spaceId: 'y5crayy7d02t', 6 | environmentId: 'dev', 7 | schemaOverrides: { 8 | documentTypes: { 9 | post: { defName: 'Post', fields: { body: { type: 'markdown' } } }, 10 | }, 11 | }, 12 | }) 13 | -------------------------------------------------------------------------------- /examples/archive/playground-contentful-starter/next-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | /// 4 | -------------------------------------------------------------------------------- /examples/archive/playground-contentful-starter/next.config.js: -------------------------------------------------------------------------------- 1 | const { withContentlayer } = require('next-contentlayer') 2 | 3 | module.exports = {} 4 | // module.exports = withContentlayer({}) 5 | -------------------------------------------------------------------------------- /examples/archive/playground-contentful-starter/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "examples-contentful-starter", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "next dev", 7 | "build": "next build", 8 | "start": "next start" 9 | }, 10 | "dependencies": { 11 | "date-fns": "^2.29.1", 12 | "next": "^12.2.3", 13 | "react": "18.2.0", 14 | "react-dom": "18.2.0" 15 | }, 16 | "devDependencies": { 17 | "@types/react": "^18.0.15", 18 | "@types/react-dom": "^18.0.6", 19 | "contentlayer": "latest", 20 | "next-contentlayer": "latest", 21 | "rehype-highlight": "^5.0.2", 22 | "typescript": "^4.7.4" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /examples/archive/playground-contentful-starter/pages/_app.tsx: -------------------------------------------------------------------------------- 1 | import '../styles/global.css' 2 | 3 | export default function App({ Component, pageProps }) { 4 | return ( 5 | <> 6 | 7 | 8 | 9 | ) 10 | } 11 | -------------------------------------------------------------------------------- /examples/archive/playground-contentful-starter/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-contentful-starter/public/favicon.ico -------------------------------------------------------------------------------- /examples/archive/playground-contentful-starter/public/images/profile.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/playground-contentful-starter/public/images/profile.jpg -------------------------------------------------------------------------------- /examples/archive/playground-contentful-starter/stackbit.yaml: -------------------------------------------------------------------------------- 1 | stackbitVersion: ~0.3.0 2 | ssgName: nextjs 3 | nodeVersion: '14' 4 | devCommand: yarn dev --port {PORT} --hostname {HOSTNAME} 5 | publishDir: out 6 | pagesDir: posts 7 | models: 8 | post: 9 | label: Post 10 | match: '*' 11 | fields: 12 | - name: title 13 | required: true 14 | description: The title of the post 15 | type: string 16 | - name: date 17 | required: true 18 | description: The date of the post 19 | type: date 20 | - name: content 21 | description: Default markdown file content 22 | label: Markdown content 23 | type: markdown 24 | hidden: true 25 | type: page 26 | -------------------------------------------------------------------------------- /examples/archive/playground-contentful-starter/styles/global.css: -------------------------------------------------------------------------------- 1 | html, 2 | body { 3 | padding: 0; 4 | margin: 0; 5 | font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, 6 | Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif; 7 | line-height: 1.6; 8 | font-size: 18px; 9 | } 10 | 11 | * { 12 | box-sizing: border-box; 13 | } 14 | 15 | a { 16 | color: #0070f3; 17 | text-decoration: none; 18 | } 19 | 20 | a:hover { 21 | text-decoration: underline; 22 | } 23 | 24 | img { 25 | max-width: 100%; 26 | display: block; 27 | } 28 | -------------------------------------------------------------------------------- /examples/archive/playground-contentful-starter/styles/utils.module.css: -------------------------------------------------------------------------------- 1 | .heading2Xl { 2 | font-size: 2.5rem; 3 | line-height: 1.2; 4 | font-weight: 800; 5 | letter-spacing: -0.05rem; 6 | margin: 1rem 0; 7 | } 8 | 9 | .headingXl { 10 | font-size: 2rem; 11 | line-height: 1.3; 12 | font-weight: 800; 13 | letter-spacing: -0.05rem; 14 | margin: 1rem 0; 15 | } 16 | 17 | .headingLg { 18 | font-size: 1.5rem; 19 | line-height: 1.4; 20 | margin: 1rem 0; 21 | } 22 | 23 | .headingMd { 24 | font-size: 1.2rem; 25 | line-height: 1.5; 26 | } 27 | 28 | .borderCircle { 29 | border-radius: 9999px; 30 | } 31 | 32 | .colorInherit { 33 | color: inherit; 34 | } 35 | 36 | .padding1px { 37 | padding-top: 1px; 38 | } 39 | 40 | .list { 41 | list-style: none; 42 | padding: 0; 43 | margin: 0; 44 | } 45 | 46 | .listItem { 47 | margin: 0 0 1.25rem; 48 | } 49 | 50 | .lightText { 51 | color: #666; 52 | } 53 | -------------------------------------------------------------------------------- /examples/archive/playground-contentful-starter/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "jsx": "preserve", 4 | "allowSyntheticDefaultImports": true, 5 | "rootDir": ".", 6 | "allowJs": true, 7 | "skipLibCheck": true, 8 | "forceConsistentCasingInFileNames": true, 9 | "esModuleInterop": true, 10 | "resolveJsonModule": true, 11 | "incremental": false, 12 | "composite": false, 13 | "noEmit": true, 14 | "target": "es5", 15 | "lib": ["dom", "dom.iterable", "esnext"], 16 | "strict": false, 17 | "module": "esnext", 18 | "moduleResolution": "node", 19 | "isolatedModules": true 20 | }, 21 | "include": ["next-env.d.ts", "**/*.tsx", "**/*.ts", "./node_modules/.contentlayer/*", "./node_modules/@types"], 22 | "exclude": ["node_modules"] 23 | } 24 | -------------------------------------------------------------------------------- /examples/archive/starter-js/.gitignore: -------------------------------------------------------------------------------- 1 | .next 2 | node_modules 3 | 4 | # Contentlayer 5 | .contentlayer 6 | -------------------------------------------------------------------------------- /examples/archive/starter-js/README.md: -------------------------------------------------------------------------------- 1 | # Starter (JS) Example 2 | 3 | ## Usage 4 | 5 | ### 1. Setup example project 6 | 7 | #### Either via Gitpod ... 8 | 9 | [![Gitpod ready-to-code](https://img.shields.io/badge/Gitpod-ready--to--code-908a85?logo=gitpod)](http://gitpod.io/#GH_OWNER=contentlayerdev,GH_REPO=contentlayer,GH_SUBDIR=examples\starter-js,GH_COMMAND=yarn/https://github.com/schickling-test/gitpod-open) 10 | 11 | #### ... or locally 12 | 13 | ```sh 14 | curl https://codeload.github.com/contentlayerdev/contentlayer/tar.gz/main | \ 15 | tar -xz --strip=2 contentlayer-main/examples/starter-js 16 | ``` 17 | 18 | ### 2. Install dependencies 19 | 20 | ```sh 21 | yarn 22 | ``` 23 | 24 | ### 3. Run dev server 25 | 26 | ```sh 27 | yarn dev 28 | ``` 29 | -------------------------------------------------------------------------------- /examples/archive/starter-js/components/date.jsx: -------------------------------------------------------------------------------- 1 | import { format, parseISO } from 'date-fns' 2 | 3 | export const FormattedDate = ({ dateString }) => { 4 | const date = parseISO(dateString) 5 | return 6 | } 7 | -------------------------------------------------------------------------------- /examples/archive/starter-js/components/layout.module.css: -------------------------------------------------------------------------------- 1 | .container { 2 | max-width: 36rem; 3 | padding: 0 1rem; 4 | margin: 3rem auto 6rem; 5 | } 6 | 7 | .header { 8 | display: flex; 9 | flex-direction: column; 10 | align-items: center; 11 | } 12 | 13 | .backToHome { 14 | margin: 3rem 0 0; 15 | } 16 | -------------------------------------------------------------------------------- /examples/archive/starter-js/contentlayer.config.js: -------------------------------------------------------------------------------- 1 | import { defineDocumentType, makeSource } from 'contentlayer/source-files' 2 | import highlight from 'rehype-highlight' 3 | 4 | export const Post = defineDocumentType(() => ({ 5 | name: 'Post', 6 | filePathPattern: `**/*.md`, 7 | fields: { 8 | title: { 9 | type: 'string', 10 | description: 'The title of the post', 11 | required: true, 12 | }, 13 | date: { 14 | type: 'date', 15 | description: 'The date of the post', 16 | required: true, 17 | }, 18 | }, 19 | })) 20 | 21 | export default makeSource({ 22 | contentDirPath: 'posts', 23 | documentTypes: [Post], 24 | markdown: { rehypePlugins: [highlight] }, 25 | }) 26 | -------------------------------------------------------------------------------- /examples/archive/starter-js/jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "jsx": "preserve", 4 | "baseUrl": ".", 5 | "paths": { 6 | "contentlayer/generated": ["./.contentlayer/generated"] 7 | } 8 | }, 9 | "include": ["**/*.jsx", "**/*.js", ".contentlayer/generated"] 10 | } 11 | -------------------------------------------------------------------------------- /examples/archive/starter-js/next.config.js: -------------------------------------------------------------------------------- 1 | const { withContentlayer } = require('next-contentlayer') 2 | 3 | module.exports = withContentlayer({}) 4 | -------------------------------------------------------------------------------- /examples/archive/starter-js/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "examples-starter-js", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "next dev", 7 | "build": "next build", 8 | "start": "next start" 9 | }, 10 | "dependencies": { 11 | "date-fns": "^2.29.1", 12 | "next": "^12.2.3", 13 | "react": "18.2.0", 14 | "react-dom": "18.2.0" 15 | }, 16 | "devDependencies": { 17 | "contentlayer": "latest", 18 | "next-contentlayer": "latest", 19 | "rehype-highlight": "^5.0.2" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /examples/archive/starter-js/pages/_app.jsx: -------------------------------------------------------------------------------- 1 | import '../styles/global.css' 2 | 3 | export default function App({ Component, pageProps }) { 4 | return ( 5 | <> 6 | 7 | 8 | 9 | ) 10 | } 11 | -------------------------------------------------------------------------------- /examples/archive/starter-js/posts/pre-rendering.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Two Forms of Pre-rendering 45' 3 | date: '2020-01-01' 4 | --- 5 | 6 | Next.js has two forms of pre-rendering: **Static Generation** and **Server-side Rendering**. The difference is in **when** it generates the HTML for a page. 7 | 8 | - **Static Generation** is the pre-rendering method that generates the HTML at **build time**. The pre-rendered HTML is then _reused_ on each request. 9 | - **Server-side Rendering** is the pre-rendering method that generates the HTML on **each request**. 10 | 11 | Importantly, Next.js lets you **choose** which pre-rendering form to use for each page. You can create a "hybrid" Next.js app by using Static Generation for most pages and using Server-side Rendering for others. 12 | -------------------------------------------------------------------------------- /examples/archive/starter-js/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/starter-js/public/favicon.ico -------------------------------------------------------------------------------- /examples/archive/starter-js/public/images/profile.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/starter-js/public/images/profile.jpg -------------------------------------------------------------------------------- /examples/archive/starter-js/styles/global.css: -------------------------------------------------------------------------------- 1 | html, 2 | body { 3 | padding: 0; 4 | margin: 0; 5 | font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, 6 | Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif; 7 | line-height: 1.6; 8 | font-size: 18px; 9 | } 10 | 11 | * { 12 | box-sizing: border-box; 13 | } 14 | 15 | a { 16 | color: #0070f3; 17 | text-decoration: none; 18 | } 19 | 20 | a:hover { 21 | text-decoration: underline; 22 | } 23 | 24 | img { 25 | max-width: 100%; 26 | display: block; 27 | } 28 | -------------------------------------------------------------------------------- /examples/archive/starter-js/styles/utils.module.css: -------------------------------------------------------------------------------- 1 | .heading2Xl { 2 | font-size: 2.5rem; 3 | line-height: 1.2; 4 | font-weight: 800; 5 | letter-spacing: -0.05rem; 6 | margin: 1rem 0; 7 | } 8 | 9 | .headingXl { 10 | font-size: 2rem; 11 | line-height: 1.3; 12 | font-weight: 800; 13 | letter-spacing: -0.05rem; 14 | margin: 1rem 0; 15 | } 16 | 17 | .headingLg { 18 | font-size: 1.5rem; 19 | line-height: 1.4; 20 | margin: 1rem 0; 21 | } 22 | 23 | .headingMd { 24 | font-size: 1.2rem; 25 | line-height: 1.5; 26 | } 27 | 28 | .borderCircle { 29 | border-radius: 9999px; 30 | } 31 | 32 | .colorInherit { 33 | color: inherit; 34 | } 35 | 36 | .padding1px { 37 | padding-top: 1px; 38 | } 39 | 40 | .list { 41 | list-style: none; 42 | padding: 0; 43 | margin: 0; 44 | } 45 | 46 | .listItem { 47 | margin: 0 0 1.25rem; 48 | } 49 | 50 | .lightText { 51 | color: #666; 52 | } 53 | -------------------------------------------------------------------------------- /examples/archive/starter/README.md: -------------------------------------------------------------------------------- 1 | # Starter Example 2 | 3 | ## Usage 4 | 5 | ### 1. Setup example project 6 | 7 | #### Either via Gitpod ... 8 | 9 | [![Gitpod ready-to-code](https://img.shields.io/badge/Gitpod-ready--to--code-908a85?logo=gitpod)](http://gitpod.io/#GH_OWNER=contentlayerdev,GH_REPO=contentlayer,GH_SUBDIR=examples\starter,GH_COMMAND=yarn/https://github.com/schickling-test/gitpod-open) 10 | 11 | #### ... or locally 12 | 13 | ```sh 14 | curl https://codeload.github.com/contentlayerdev/contentlayer/tar.gz/main | \ 15 | tar -xz --strip=2 contentlayer-main/examples/starter 16 | ``` 17 | 18 | ### 2. Install dependencies 19 | 20 | ```sh 21 | yarn 22 | ``` 23 | 24 | ### 3. Run dev server 25 | 26 | ```sh 27 | yarn dev 28 | ``` 29 | -------------------------------------------------------------------------------- /examples/archive/starter/components/date.tsx: -------------------------------------------------------------------------------- 1 | import { format, parseISO } from 'date-fns' 2 | import type { FC } from 'react' 3 | 4 | export const FormattedDate: FC<{ dateString: string }> = ({ dateString }) => { 5 | const date = parseISO(dateString) 6 | return 7 | } 8 | -------------------------------------------------------------------------------- /examples/archive/starter/components/layout.module.css: -------------------------------------------------------------------------------- 1 | .container { 2 | max-width: 36rem; 3 | padding: 0 1rem; 4 | margin: 3rem auto 6rem; 5 | } 6 | 7 | .header { 8 | display: flex; 9 | flex-direction: column; 10 | align-items: center; 11 | } 12 | 13 | .backToHome { 14 | margin: 3rem 0 0; 15 | } 16 | -------------------------------------------------------------------------------- /examples/archive/starter/contentlayer.config.ts: -------------------------------------------------------------------------------- 1 | import { defineDocumentType, makeSource } from 'contentlayer/source-files' 2 | import highlight from 'rehype-highlight' 3 | 4 | export const Post = defineDocumentType(() => ({ 5 | name: 'Post', 6 | fields: { 7 | title: { 8 | type: 'string', 9 | description: 'The title of the post', 10 | required: true, 11 | }, 12 | date: { 13 | type: 'date', 14 | description: 'The date of the post', 15 | required: true, 16 | }, 17 | }, 18 | })) 19 | 20 | export default makeSource({ 21 | contentDirPath: 'posts', 22 | documentTypes: [Post], 23 | markdown: { rehypePlugins: [highlight] }, 24 | }) 25 | -------------------------------------------------------------------------------- /examples/archive/starter/next-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | 4 | // NOTE: This file should not be edited 5 | // see https://nextjs.org/docs/basic-features/typescript for more information. 6 | -------------------------------------------------------------------------------- /examples/archive/starter/next.config.js: -------------------------------------------------------------------------------- 1 | const { withContentlayer } = require('next-contentlayer') 2 | 3 | module.exports = withContentlayer({}) 4 | -------------------------------------------------------------------------------- /examples/archive/starter/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "examples-starter", 3 | "private": true, 4 | "scripts": { 5 | "dev": "next dev", 6 | "build": "next build", 7 | "start": "next start" 8 | }, 9 | "dependencies": { 10 | "date-fns": "^2.29.1", 11 | "next": "^12.2.3", 12 | "react": "18.2.0", 13 | "react-dom": "18.2.0" 14 | }, 15 | "devDependencies": { 16 | "@types/react": "^18.0.15", 17 | "@types/react-dom": "^18.0.6", 18 | "contentlayer": "latest", 19 | "next-contentlayer": "latest", 20 | "rehype-highlight": "^5.0.2", 21 | "typescript": "^4.7.4" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /examples/archive/starter/pages/_app.tsx: -------------------------------------------------------------------------------- 1 | import '../styles/global.css' 2 | 3 | export default function App({ Component, pageProps }) { 4 | return ( 5 | <> 6 | 7 | 8 | 9 | ) 10 | } 11 | -------------------------------------------------------------------------------- /examples/archive/starter/posts/pre-rendering.md: -------------------------------------------------------------------------------- 1 | --- 2 | type: 'Post' 3 | title: 'Two Forms of Pre-rendering 49' 4 | someOtherField: hi 5 | date: '2020-01-01' 6 | --- 7 | 8 | Next.js has two forms of pre-rendering: **Static Generation** and **Server-side Rendering**. The difference is in **when** it generates the HTML for a page. 9 | 10 | - **Static Generation** is the pre-rendering method that generates the HTML at **build time**. The pre-rendered HTML is then _reused_ on each request. 11 | - **Server-side Rendering** is the pre-rendering method that generates the HTML on **each request**. 12 | 13 | Importantly, Next.js lets you **choose** which pre-rendering form to use for each page. You can create a "hybrid" Next.js app by using Static Generation for most pages and using Server-side Rendering for others. 14 | -------------------------------------------------------------------------------- /examples/archive/starter/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/starter/public/favicon.ico -------------------------------------------------------------------------------- /examples/archive/starter/public/images/profile.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/archive/starter/public/images/profile.jpg -------------------------------------------------------------------------------- /examples/archive/starter/styles/global.css: -------------------------------------------------------------------------------- 1 | html, 2 | body { 3 | padding: 0; 4 | margin: 0; 5 | font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, 6 | Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif; 7 | line-height: 1.6; 8 | font-size: 18px; 9 | } 10 | 11 | * { 12 | box-sizing: border-box; 13 | } 14 | 15 | a { 16 | color: #0070f3; 17 | text-decoration: none; 18 | } 19 | 20 | a:hover { 21 | text-decoration: underline; 22 | } 23 | 24 | img { 25 | max-width: 100%; 26 | display: block; 27 | } 28 | -------------------------------------------------------------------------------- /examples/archive/starter/styles/utils.module.css: -------------------------------------------------------------------------------- 1 | .heading2Xl { 2 | font-size: 2.5rem; 3 | line-height: 1.2; 4 | font-weight: 800; 5 | letter-spacing: -0.05rem; 6 | margin: 1rem 0; 7 | } 8 | 9 | .headingXl { 10 | font-size: 2rem; 11 | line-height: 1.3; 12 | font-weight: 800; 13 | letter-spacing: -0.05rem; 14 | margin: 1rem 0; 15 | } 16 | 17 | .headingLg { 18 | font-size: 1.5rem; 19 | line-height: 1.4; 20 | margin: 1rem 0; 21 | } 22 | 23 | .headingMd { 24 | font-size: 1.2rem; 25 | line-height: 1.5; 26 | } 27 | 28 | .borderCircle { 29 | border-radius: 9999px; 30 | } 31 | 32 | .colorInherit { 33 | color: inherit; 34 | } 35 | 36 | .padding1px { 37 | padding-top: 1px; 38 | } 39 | 40 | .list { 41 | list-style: none; 42 | padding: 0; 43 | margin: 0; 44 | } 45 | 46 | .listItem { 47 | margin: 0 0 1.25rem; 48 | } 49 | 50 | .lightText { 51 | color: #666; 52 | } 53 | -------------------------------------------------------------------------------- /examples/archive/starter/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "jsx": "preserve", 4 | "allowSyntheticDefaultImports": true, 5 | "rootDir": ".", 6 | "allowJs": true, 7 | "skipLibCheck": true, 8 | "forceConsistentCasingInFileNames": true, 9 | "esModuleInterop": true, 10 | "resolveJsonModule": true, 11 | "incremental": false, 12 | "composite": false, 13 | "noEmit": true, 14 | "target": "es5", 15 | "lib": ["dom", "dom.iterable", "esnext"], 16 | "strict": false, 17 | "module": "esnext", 18 | "moduleResolution": "node", 19 | "isolatedModules": true, 20 | "baseUrl": ".", 21 | "paths": { 22 | "contentlayer/generated": ["./.contentlayer/generated"] 23 | } 24 | }, 25 | "include": ["next-env.d.ts", "**/*.tsx", "**/*.ts", ".contentlayer/generated"], 26 | "exclude": ["node_modules"] 27 | } 28 | -------------------------------------------------------------------------------- /examples/next-images/.gitignore: -------------------------------------------------------------------------------- 1 | # dependencies 2 | node_modules 3 | 4 | # next 5 | dist 6 | .next 7 | 8 | # contentlayer 9 | .contentlayer 10 | 11 | # yarn 12 | yarn.lock 13 | yarn-error.log 14 | 15 | # mac 16 | .DS_Store 17 | -------------------------------------------------------------------------------- /examples/next-images/app/layout.tsx: -------------------------------------------------------------------------------- 1 | import '../styles/globals.css' 2 | 3 | import { Header } from '../components/Header' 4 | 5 | export default function RootLayout({ children }: { children: React.ReactNode }) { 6 | return ( 7 | 8 | 9 | Contentlayer Next.js Example 10 | 11 | 12 | 13 |
14 |
{children}
15 | 16 | 17 | ) 18 | } 19 | -------------------------------------------------------------------------------- /examples/next-images/components/Button.tsx: -------------------------------------------------------------------------------- 1 | import { FC } from 'react' 2 | import React from 'react' 3 | 4 | export const Button: FC<{ title: string }> = ({ title }) => ( 5 |
alert('Hi')} 8 | > 9 | {title} 10 |
11 | ) 12 | -------------------------------------------------------------------------------- /examples/next-images/contentlayer.config.ts: -------------------------------------------------------------------------------- 1 | import { defineDocumentType, makeSource } from 'contentlayer/source-files' 2 | 3 | const Post = defineDocumentType(() => ({ 4 | name: 'Post', 5 | filePathPattern: `**/*.mdx`, 6 | contentType: 'mdx', 7 | fields: { 8 | title: { 9 | type: 'string', 10 | description: 'The title of the post', 11 | required: true, 12 | }, 13 | date: { 14 | type: 'date', 15 | description: 'The date of the post', 16 | required: true, 17 | }, 18 | cover: { 19 | type: 'image', 20 | required: false, 21 | }, 22 | }, 23 | computedFields: { 24 | url: { 25 | type: 'string', 26 | resolve: (doc) => `/posts/${doc._raw.flattenedPath}`, 27 | }, 28 | }, 29 | })) 30 | 31 | export default makeSource({ 32 | contentDirPath: 'posts', 33 | documentTypes: [Post], 34 | }) 35 | -------------------------------------------------------------------------------- /examples/next-images/next-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | 4 | // NOTE: This file should not be edited 5 | // see https://nextjs.org/docs/basic-features/typescript for more information. 6 | -------------------------------------------------------------------------------- /examples/next-images/next.config.js: -------------------------------------------------------------------------------- 1 | const { withContentlayer } = require("next-contentlayer"); 2 | 3 | /** @type {import('next').NextConfig} */ 4 | const nextConfig = { 5 | experimental: { 6 | appDir: true, 7 | }, 8 | }; 9 | 10 | module.exports = withContentlayer(nextConfig); 11 | -------------------------------------------------------------------------------- /examples/next-images/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "next-images", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "next dev", 7 | "build": "next build", 8 | "start": "next start" 9 | }, 10 | "dependencies": { 11 | "contentlayer": "latest", 12 | "date-fns": "2.30.0", 13 | "next": "13.4.7", 14 | "next-contentlayer": "latest", 15 | "react": "18.2.0", 16 | "react-dom": "18.2.0" 17 | }, 18 | "devDependencies": { 19 | "@types/react": "18.2.14", 20 | "autoprefixer": "^10.4.14", 21 | "postcss": "^8.4.24", 22 | "tailwindcss": "^3.3.2", 23 | "typescript": "5.1.6" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /examples/next-images/postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | } 7 | -------------------------------------------------------------------------------- /examples/next-images/posts/change-me.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: Change me! 3 | date: 2022-03-11 4 | cover: '../public/images/mark-neal-unsplash.jpg' 5 | --- 6 | 7 | When you change a source file, Contentlayer automatically updates the content cache, which prompts Next.js to reload the content on screen. 8 | -------------------------------------------------------------------------------- /examples/next-images/posts/click-me.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: Click me! 3 | date: 2022-02-28 4 | --- 5 | 6 | Blog posts have their own pages. The content source is a markdown file, parsed to HTML by Contentlayer. 7 | -------------------------------------------------------------------------------- /examples/next-images/posts/what-is-contentlayer.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: What is Contentlayer? 3 | date: 2022-02-22 4 | --- 5 | 6 | **Contentlayer makes working with content easy.** It is a content preprocessor that validates and transforms your content into type-safe JSON you can easily import into your application. 7 | -------------------------------------------------------------------------------- /examples/next-images/public/images/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/next-images/public/images/favicon.png -------------------------------------------------------------------------------- /examples/next-images/public/images/mark-neal-unsplash.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/next-images/public/images/mark-neal-unsplash.jpg -------------------------------------------------------------------------------- /examples/next-images/styles/globals.css: -------------------------------------------------------------------------------- 1 | @import url("https://fonts.googleapis.com/css2?family=Inter:wght@300;400;700&display=swap"); 2 | 3 | @tailwind base; 4 | @tailwind components; 5 | @tailwind utilities; 6 | 7 | p { 8 | @apply mb-4; 9 | } 10 | 11 | h1, 12 | h2, 13 | h3, 14 | h4, 15 | h5, 16 | h6 { 17 | @apply font-bold 18 | mb-1; 19 | } 20 | 21 | h1 { 22 | @apply text-3xl; 23 | } 24 | 25 | h2 { 26 | @apply text-xl; 27 | } 28 | -------------------------------------------------------------------------------- /examples/next-images/tailwind.config.js: -------------------------------------------------------------------------------- 1 | const defaultTheme = require("tailwindcss/defaultTheme"); 2 | 3 | module.exports = { 4 | content: [ 5 | "./app/**/*.{js,ts,jsx,tsx}", 6 | "./pages/**/*.{js,ts,jsx,tsx}", 7 | "./components/**/*.{js,ts,jsx,tsx}", 8 | ], 9 | theme: { 10 | extend: { 11 | fontFamily: { 12 | sans: ["Inter", ...defaultTheme.fontFamily.sans], 13 | }, 14 | }, 15 | }, 16 | plugins: [], 17 | }; 18 | -------------------------------------------------------------------------------- /examples/next-images/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "lib": ["dom", "dom.iterable", "esnext"], 5 | "allowJs": true, 6 | "skipLibCheck": true, 7 | "strict": false, 8 | "forceConsistentCasingInFileNames": true, 9 | "noEmit": true, 10 | "incremental": true, 11 | "esModuleInterop": true, 12 | "module": "esnext", 13 | "moduleResolution": "node", 14 | "resolveJsonModule": true, 15 | "isolatedModules": true, 16 | "jsx": "preserve", 17 | "baseUrl": ".", 18 | "paths": { 19 | "contentlayer/generated": ["./.contentlayer/generated"] 20 | }, 21 | "plugins": [{ "name": "next" }] 22 | }, 23 | "include": [ 24 | "next-env.d.ts", 25 | "**/*.ts", 26 | "**/*.tsx", 27 | ".contentlayer/generated", 28 | ".next/types/**/*.ts" 29 | ], 30 | "exclude": ["node_modules"] 31 | } 32 | -------------------------------------------------------------------------------- /examples/next-rsc-dynamic/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | .next 4 | .contentlayer 5 | yarn.lock 6 | .DS_Store 7 | 8 | nextjs-repo* 9 | .vercel 10 | -------------------------------------------------------------------------------- /examples/next-rsc-dynamic/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "typescript.tsdk": "node_modules/typescript/lib", 3 | "typescript.enablePromptUseWorkspaceTsdk": true 4 | } -------------------------------------------------------------------------------- /examples/next-rsc-dynamic/README.md: -------------------------------------------------------------------------------- 1 | # Next.js Contentlayer Example 2 | 3 | ## Demo 4 | 5 | View the deployed project: [Demo](https://next-contentlayer-example.vercel.app/) 6 | 7 | ## Try it Now 8 | 9 | [![Gitpod ready-to-code](https://img.shields.io/badge/Gitpod-ready--to--code-908a85?logo=gitpod)](http://gitpod.io/#https://github.com/contentlayerdev/next-contentlayer-example) 10 | 11 | ## Local Installation 12 | 13 | Clone the project: 14 | 15 | git clone git@github.com:contentlayerdev/next-contentlayer-example.git 16 | 17 | Install dependencies: 18 | 19 | yarn 20 | 21 | Run dev server: 22 | 23 | yarn dev 24 | -------------------------------------------------------------------------------- /examples/next-rsc-dynamic/app/[...slug]/head.tsx: -------------------------------------------------------------------------------- 1 | import { allPosts } from 'contentlayer/generated' 2 | 3 | export default function Head({ params }: { params: { slug: string[] } }) { 4 | const slug = params.slug.join('/') 5 | const post = allPosts.find((post) => post._raw.flattenedPath === slug) 6 | 7 | return ( 8 | <> 9 | {post?.url} 10 | 11 | ) 12 | } 13 | -------------------------------------------------------------------------------- /examples/next-rsc-dynamic/app/[...slug]/page.tsx: -------------------------------------------------------------------------------- 1 | import { allPosts } from 'contentlayer/generated' 2 | 3 | export const generateStaticParams = async () => allPosts.map((post) => ({ slug: post._raw.flattenedPath.split('/') })) 4 | 5 | const PostLayout = async ({ params }: { params: { slug: string[]; tag: string } }) => { 6 | const slug = params.slug.join('/') 7 | const post = allPosts.find((post) => post._raw.flattenedPath === slug) 8 | 9 | if (post === undefined) { 10 | return
Post not found ({slug})
11 | } 12 | 13 | return ( 14 |
15 |
16 |

{post.url}

17 |
18 |
19 |
20 | ) 21 | } 22 | 23 | export default PostLayout 24 | -------------------------------------------------------------------------------- /examples/next-rsc-dynamic/app/layout.tsx: -------------------------------------------------------------------------------- 1 | import '../styles/globals.css' 2 | 3 | import { Header } from '../components/Header' 4 | 5 | export default function RootLayout({ children }: { children: React.ReactNode }) { 6 | return ( 7 | 8 | 9 | Contentlayer Next.js Example 10 | 11 | 12 | 13 |
14 |
{children}
15 | 16 | 17 | ) 18 | } 19 | -------------------------------------------------------------------------------- /examples/next-rsc-dynamic/app/page.tsx: -------------------------------------------------------------------------------- 1 | import Link from 'next/link' 2 | import { allPosts, Post } from 'contentlayer/generated' 3 | 4 | export default async function Home({ params }: { params: { tag: string } }) { 5 | return ( 6 |
7 |

Next.js docs

8 |

Branch/Tag: static

9 | 10 | {allPosts.map((post, idx) => ( 11 |
12 | {post.url} 13 |
14 | // 15 | ))} 16 |
17 | ) 18 | } 19 | -------------------------------------------------------------------------------- /examples/next-rsc-dynamic/app/v/page.tsx: -------------------------------------------------------------------------------- 1 | import { redirect } from 'next/navigation' 2 | 3 | export default async function Page() { 4 | return redirect('/v/canary') 5 | } 6 | -------------------------------------------------------------------------------- /examples/next-rsc-dynamic/components/Button.tsx: -------------------------------------------------------------------------------- 1 | import { FC } from 'react' 2 | import React from 'react' 3 | 4 | export const Button: FC<{ title: string }> = ({ title }) => ( 5 |
alert('Hi')} 8 | > 9 | {title} 10 |
11 | ) 12 | -------------------------------------------------------------------------------- /examples/next-rsc-dynamic/content/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/next-rsc-dynamic/content/.gitkeep -------------------------------------------------------------------------------- /examples/next-rsc-dynamic/next-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | 4 | // NOTE: This file should not be edited 5 | // see https://nextjs.org/docs/basic-features/typescript for more information. 6 | -------------------------------------------------------------------------------- /examples/next-rsc-dynamic/next.config.js: -------------------------------------------------------------------------------- 1 | const { withContentlayer } = require('next-contentlayer') 2 | 3 | module.exports = withContentlayer({ 4 | experimental: { appDir: true, }, 5 | }) -------------------------------------------------------------------------------- /examples/next-rsc-dynamic/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "next-rsc-dynamic", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "next dev", 7 | "build": "next build", 8 | "start": "next start" 9 | }, 10 | "dependencies": { 11 | "contentlayer": "latest", 12 | "date-fns": "2.30.0", 13 | "next": "13.4.7", 14 | "next-contentlayer": "latest", 15 | "react": "18.2.0", 16 | "react-dom": "18.2.0" 17 | }, 18 | "devDependencies": { 19 | "@types/react": "18.2.14", 20 | "autoprefixer": "^10.4.14", 21 | "postcss": "^8.4.24", 22 | "tailwindcss": "^3.3.2", 23 | "typescript": "5.1.6" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /examples/next-rsc-dynamic/postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | } 7 | -------------------------------------------------------------------------------- /examples/next-rsc-dynamic/posts/change-me.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Change me! 3 | date: 2022-03-11 4 | --- 5 | 6 | When you change a source file, Contentlayer automatically updates the content cache, which prompts Next.js to reload the content on screen. 7 | -------------------------------------------------------------------------------- /examples/next-rsc-dynamic/posts/click-me.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Click me! 3 | date: 2022-02-28 4 | --- 5 | 6 | Blog posts have their own pages. The content source is a markdown file, parsed to HTML by Contentlayer. 7 | -------------------------------------------------------------------------------- /examples/next-rsc-dynamic/posts/what-is-contentlayer.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: What is Contentlayer? 3 | date: 2022-02-22 4 | --- 5 | 6 | **Contentlayer makes working with content easy.** It is a content preprocessor that validates and transforms your content into type-safe JSON you can easily import into your application. 7 | -------------------------------------------------------------------------------- /examples/next-rsc-dynamic/public/images/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/examples/next-rsc-dynamic/public/images/favicon.png -------------------------------------------------------------------------------- /examples/next-rsc-dynamic/styles/globals.css: -------------------------------------------------------------------------------- 1 | @import url("https://fonts.googleapis.com/css2?family=Inter:wght@300;400;700&display=swap"); 2 | 3 | @tailwind base; 4 | @tailwind components; 5 | @tailwind utilities; 6 | 7 | p { 8 | @apply mb-4; 9 | } 10 | 11 | h1, 12 | h2, 13 | h3, 14 | h4, 15 | h5, 16 | h6 { 17 | @apply font-bold 18 | mb-1; 19 | } 20 | 21 | h1 { 22 | @apply text-3xl; 23 | } 24 | 25 | h2 { 26 | @apply text-xl; 27 | } 28 | -------------------------------------------------------------------------------- /examples/next-rsc-dynamic/tailwind.config.js: -------------------------------------------------------------------------------- 1 | const defaultTheme = require("tailwindcss/defaultTheme"); 2 | 3 | module.exports = { 4 | content: [ 5 | "./pages/**/*.{js,ts,jsx,tsx}", 6 | "./components/**/*.{js,ts,jsx,tsx}", 7 | ], 8 | theme: { 9 | extend: { 10 | fontFamily: { 11 | sans: ["Inter", ...defaultTheme.fontFamily.sans], 12 | }, 13 | }, 14 | }, 15 | plugins: [], 16 | }; 17 | -------------------------------------------------------------------------------- /examples/next-rsc-dynamic/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "lib": ["dom", "dom.iterable", "esnext"], 5 | "allowJs": true, 6 | "skipLibCheck": true, 7 | "strict": false, 8 | "forceConsistentCasingInFileNames": true, 9 | "noEmit": true, 10 | "incremental": true, 11 | "esModuleInterop": true, 12 | "module": "esnext", 13 | "moduleResolution": "node", 14 | "resolveJsonModule": true, 15 | "isolatedModules": true, 16 | "jsx": "preserve", 17 | "baseUrl": ".", 18 | "paths": { 19 | "contentlayer/generated": ["./.contentlayer/generated"] 20 | }, 21 | "plugins": [{ "name": "next" }] 22 | }, 23 | "include": [ 24 | "next-env.d.ts", 25 | "**/*.ts", 26 | "**/*.tsx", 27 | ".contentlayer/generated", 28 | ".next/types/**/*.ts" 29 | ], 30 | "exclude": ["node_modules"] 31 | } 32 | -------------------------------------------------------------------------------- /examples/node-script-mdx/my-script.mjs: -------------------------------------------------------------------------------- 1 | import { allPosts } from './.contentlayer/generated/index.mjs' 2 | 3 | console.log(allPosts) 4 | -------------------------------------------------------------------------------- /examples/node-script-mdx/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "node-script-mdx-example", 3 | "private": true, 4 | "scripts": { 5 | "start": "contentlayer build && node --experimental-json-modules my-script.mjs" 6 | }, 7 | "dependencies": { 8 | "contentlayer": "latest" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /examples/node-script-mdx/posts/change-me.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: Change me! 3 | date: 2022-03-11 4 | --- 5 | 6 | When you change a source file, Contentlayer automatically updates the content cache, which prompts Next.js to reload the content on screen. 7 | -------------------------------------------------------------------------------- /examples/node-script-mdx/posts/click-me.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: Click me! 3 | date: 2022-02-28 4 | --- 5 | 6 | Blog posts have their own pages. The content source is a markdown file, parsed to HTML by Contentlayer. 7 | -------------------------------------------------------------------------------- /examples/node-script-mdx/posts/what-is-contentlayer.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: What is Contentlayer? 3 | date: 2022-02-22 4 | --- 5 | 6 | **Contentlayer makes working with content easy.** It is a content preprocessor that validates and transforms your content into type-safe JSON you can easily import into your application. 7 | -------------------------------------------------------------------------------- /examples/node-script-remote-content/.gitignore: -------------------------------------------------------------------------------- 1 | nextjs-repo -------------------------------------------------------------------------------- /examples/node-script-remote-content/my-script.mjs: -------------------------------------------------------------------------------- 1 | import { allPosts } from './.contentlayer/generated/index.mjs' 2 | 3 | const postUrls = allPosts.map(post => post.url) 4 | 5 | console.log(`Found ${postUrls.length} posts:`); 6 | console.log(postUrls) 7 | -------------------------------------------------------------------------------- /examples/node-script-remote-content/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "node-script-remote-content-example", 3 | "private": true, 4 | "scripts": { 5 | "start": "contentlayer build && node --experimental-json-modules my-script.mjs" 6 | }, 7 | "dependencies": { 8 | "contentlayer": "latest" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /examples/node-script/contentlayer.config.ts: -------------------------------------------------------------------------------- 1 | import { defineDocumentType, makeSource } from 'contentlayer/source-files' 2 | 3 | const Post = defineDocumentType(() => ({ 4 | name: 'Post', 5 | filePathPattern: `**/*.md`, 6 | fields: { 7 | title: { 8 | type: 'string', 9 | description: 'The title of the post', 10 | required: true, 11 | }, 12 | date: { 13 | type: 'date', 14 | description: 'The date of the post', 15 | required: true, 16 | }, 17 | }, 18 | computedFields: { 19 | url: { 20 | type: 'string', 21 | resolve: (doc) => `/posts/${doc._raw.flattenedPath}`, 22 | }, 23 | }, 24 | })) 25 | 26 | export default makeSource({ 27 | contentDirPath: 'posts', 28 | documentTypes: [Post], 29 | disableImportAliasWarning: true, 30 | }) 31 | -------------------------------------------------------------------------------- /examples/node-script/my-script.mjs: -------------------------------------------------------------------------------- 1 | import { allPosts } from './.contentlayer/generated/index.mjs' 2 | 3 | console.log(allPosts) 4 | -------------------------------------------------------------------------------- /examples/node-script/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "node-script-example", 3 | "private": true, 4 | "scripts": { 5 | "start": "contentlayer build && node --experimental-json-modules my-script.mjs" 6 | }, 7 | "dependencies": { 8 | "contentlayer": "latest" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /examples/node-script/posts/change-me.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Change me! 3 | date: 2022-03-11 4 | --- 5 | 6 | When you change a source file, Contentlayer automatically updates the content cache, which prompts Next.js to reload the content on screen. 7 | -------------------------------------------------------------------------------- /examples/node-script/posts/click-me.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Click me! 3 | date: 2022-02-28 4 | --- 5 | 6 | Blog posts have their own pages. The content source is a markdown file, parsed to HTML by Contentlayer. 7 | -------------------------------------------------------------------------------- /examples/node-script/posts/what-is-contentlayer.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: What is Contentlayer? 3 | date: 2022-02-22 4 | --- 5 | 6 | **Contentlayer makes working with content easy.** It is a content preprocessor that validates and transforms your content into type-safe JSON you can easily import into your application. 7 | -------------------------------------------------------------------------------- /flake.nix: -------------------------------------------------------------------------------- 1 | { 2 | inputs = { 3 | nixpkgs.url = "github:NixOS/nixpkgs/master"; 4 | flake-utils.url = "github:numtide/flake-utils"; 5 | }; 6 | 7 | outputs = { self, nixpkgs, flake-utils }: 8 | flake-utils.lib.eachDefaultSystem (system: 9 | let 10 | pkgs = nixpkgs.legacyPackages.${system}; 11 | in 12 | { 13 | 14 | devShell = with pkgs; pkgs.mkShell { 15 | buildInputs = [ 16 | nodejs_20 17 | (yarn.override { nodejs = nodejs_20; }) 18 | ]; 19 | }; 20 | 21 | }); 22 | } 23 | -------------------------------------------------------------------------------- /packages/@contentlayer/cli/README.md: -------------------------------------------------------------------------------- 1 | # @contentlayer/cli 2 | 3 | Currently (in order to keep the build setup minimal) this CLI package only contains the CLI source but cannot be run directly. Instead it needs to be built & run via `packages/contentlayer`. 4 | -------------------------------------------------------------------------------- /packages/@contentlayer/cli/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@contentlayer/cli", 3 | "version": "0.3.4", 4 | "type": "module", 5 | "exports": "./dist/index.js", 6 | "types": "./dist/index.d.ts", 7 | "files": [ 8 | "./dist/**/*.{js,ts,map}", 9 | "./src", 10 | "./package.json" 11 | ], 12 | "scripts": { 13 | "test": "echo No tests yet" 14 | }, 15 | "dependencies": { 16 | "@contentlayer/core": "workspace:*", 17 | "@contentlayer/utils": "workspace:*", 18 | "clipanion": "^3.2.1", 19 | "typanion": "^3.12.1" 20 | }, 21 | "devDependencies": { 22 | "@types/node": "^20.3.2" 23 | }, 24 | "license": "MIT" 25 | } 26 | -------------------------------------------------------------------------------- /packages/@contentlayer/cli/src/commands/DefaultCommand.ts: -------------------------------------------------------------------------------- 1 | import { OT, pipe, T } from '@contentlayer/utils/effect' 2 | import { Command } from 'clipanion' 3 | 4 | import { BaseCommand } from './_BaseCommand.js' 5 | 6 | export class DefaultCommand extends BaseCommand { 7 | static paths = [Command.Default] 8 | 9 | executeSafe = () => 10 | pipe( 11 | T.succeedWith(() => console.log(this.cli.usage())), 12 | OT.withSpan('@contentlayer/cli/commands/DefaultCommand:executeSafe', { attributes: { cwd: process.cwd() } }), 13 | ) 14 | } 15 | -------------------------------------------------------------------------------- /packages/@contentlayer/cli/src/global.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'eval' 2 | -------------------------------------------------------------------------------- /packages/@contentlayer/cli/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "module": "ES2020", 5 | "rootDir": "./src", 6 | "outDir": "./dist", 7 | "tsBuildInfoFile": "./dist/.tsbuildinfo.json" 8 | }, 9 | "include": ["./src"], 10 | "references": [{ "path": "../utils" }, { "path": "../core" }] 11 | } 12 | -------------------------------------------------------------------------------- /packages/@contentlayer/client/.gitignore: -------------------------------------------------------------------------------- 1 | /types -------------------------------------------------------------------------------- /packages/@contentlayer/client/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@contentlayer/client", 3 | "version": "0.3.4", 4 | "type": "module", 5 | "exports": "./dist/index.js", 6 | "types": "./dist/index.d.ts", 7 | "files": [ 8 | "./dist/**/*.{js,ts,map}", 9 | "./src", 10 | "./package.json" 11 | ], 12 | "scripts": { 13 | "test": "echo No tests yet" 14 | }, 15 | "dependencies": { 16 | "@contentlayer/core": "workspace:*" 17 | }, 18 | "license": "MIT" 19 | } 20 | -------------------------------------------------------------------------------- /packages/@contentlayer/client/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './guards.js' 2 | export * from './utils.js' 3 | -------------------------------------------------------------------------------- /packages/@contentlayer/client/src/utils.ts: -------------------------------------------------------------------------------- 1 | type ConvertUndefined = OrUndefined<{ 2 | [K in keyof T as undefined extends T[K] ? K : never]-?: T[K] 3 | }> 4 | type OrUndefined = { [K in keyof T]: T[K] | undefined } 5 | type PickRequired = { 6 | [K in keyof T as undefined extends T[K] ? never : K]: T[K] 7 | } 8 | type ConvertPick = ConvertUndefined & PickRequired 9 | 10 | export const pick = (obj: Obj, keys: Keys[]): ConvertPick<{ [K in Keys]: Obj[K] }> => { 11 | return keys.reduce((acc, key) => { 12 | acc[key] = obj[key] 13 | return acc 14 | }, {} as any) 15 | } 16 | -------------------------------------------------------------------------------- /packages/@contentlayer/client/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "module": "ES2020", 5 | "rootDir": "./src", 6 | "outDir": "./dist", 7 | "tsBuildInfoFile": "./dist/.tsbuildinfo.json" 8 | }, 9 | "include": ["./src"], 10 | "references": [{ "path": "../utils" }, { "path": "../core" }] 11 | } 12 | -------------------------------------------------------------------------------- /packages/@contentlayer/core/src/ArtifactsDir.ts: -------------------------------------------------------------------------------- 1 | export * as ArtifactsDir from './_ArtifactsDir.js' 2 | -------------------------------------------------------------------------------- /packages/@contentlayer/core/src/ambient.d.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | declare module 'markdown-wasm/dist/markdown.node.js' { 3 | export const parse: typeof import('markdown-wasm').parse 4 | } 5 | -------------------------------------------------------------------------------- /packages/@contentlayer/core/src/generation/common.ts: -------------------------------------------------------------------------------- 1 | import * as utils from '@contentlayer/utils' 2 | 3 | import type { DocumentTypeDef } from '../schema/index.js' 4 | 5 | export const autogeneratedNote = `NOTE This file is auto-generated by Contentlayer` 6 | 7 | export const getDataVariableName = ({ docDef }: { docDef: DocumentTypeDef }): string => { 8 | if (docDef.isSingleton) { 9 | return utils.lowercaseFirstChar(utils.inflection.singularize(docDef.name)) 10 | } else { 11 | return 'all' + utils.uppercaseFirstChar(utils.inflection.pluralize(docDef.name)) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /packages/@contentlayer/core/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './generation/generate-dotpkg.js' 2 | export * from './generation/generate-types.js' 3 | export * from './DataCache.js' 4 | export * from './data-types.js' 5 | export * from './cwd.js' 6 | export * from './gen.js' 7 | export * from './errors.js' 8 | export * from './getConfig/index.js' 9 | export * from './runMain.js' 10 | export * from './markdown/markdown.js' 11 | export * from './markdown/mdx.js' 12 | export * from './markdown/unified.js' 13 | export * from './plugin.js' 14 | export * from './schema/index.js' 15 | export * from './ArtifactsDir.js' 16 | export * from './validate-tsconfig.js' 17 | export * from './dynamic-build.js' 18 | -------------------------------------------------------------------------------- /packages/@contentlayer/core/src/markdown/unified.ts: -------------------------------------------------------------------------------- 1 | import type * as unified from 'unified' 2 | 3 | import type { RawDocumentData } from '../data-types.js' 4 | 5 | /** 6 | * Unified plugin that adds the raw document data to the vfile under `vfile.data.rawDocumentData` 7 | * 8 | * Contentlayer uses this plugin by default. 9 | */ 10 | export const addRawDocumentToVFile = (rawDocumentData: RawDocumentData) => (): unified.Transformer => (_, vfile) => { 11 | Object.assign(vfile.data, { rawDocumentData }) 12 | } 13 | -------------------------------------------------------------------------------- /packages/@contentlayer/core/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "module": "ES2020", 5 | "rootDir": "./src", 6 | "outDir": "./dist", 7 | "tsBuildInfoFile": "./dist/.tsbuildinfo.json" 8 | }, 9 | "include": ["./src"], 10 | "references": [{ "path": "../utils" }] 11 | } 12 | -------------------------------------------------------------------------------- /packages/@contentlayer/experimental-source-files-stackbit/src/__test__/__snapshots__/stackbit.spec.ts.snap: -------------------------------------------------------------------------------- 1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 2 | 3 | exports[`kitchen-sink 1`] = ` 4 | { 5 | "documentTypeDefMap": {}, 6 | "hash": "NOT_USED", 7 | "nestedTypeDefMap": {}, 8 | } 9 | `; 10 | 11 | exports[`next-starter 1`] = ` 12 | { 13 | "documentTypeDefMap": {}, 14 | "hash": "NOT_USED", 15 | "nestedTypeDefMap": {}, 16 | } 17 | `; 18 | 19 | exports[`small-business 1`] = ` 20 | { 21 | "documentTypeDefMap": {}, 22 | "hash": "NOT_USED", 23 | "nestedTypeDefMap": {}, 24 | } 25 | `; 26 | -------------------------------------------------------------------------------- /packages/@contentlayer/experimental-source-files-stackbit/src/__test__/fixtures/kitchen-sink/.stackbit/models/data_model_1.yaml: -------------------------------------------------------------------------------- 1 | name: data_model_1 2 | type: data 3 | labelField: string_field 4 | filePath: "{slug}.md" 5 | fields: 6 | - type: string 7 | name: string_field 8 | - type: string 9 | name: string_required 10 | required: true 11 | - type: reference 12 | name: referenceSingleToNonDuplicatable 13 | models: [data_model_1] 14 | - type: reference 15 | name: referenceSingleToDuplicatable 16 | models: [data_model_2] 17 | -------------------------------------------------------------------------------- /packages/@contentlayer/experimental-source-files-stackbit/src/__test__/fixtures/kitchen-sink/.stackbit/models/data_model_2.yaml: -------------------------------------------------------------------------------- 1 | name: data_model_2 2 | type: data 3 | labelField: string_field 4 | filePath: "{slug}.md" 5 | fields: 6 | - type: string 7 | name: string_field 8 | - type: string 9 | name: string_default 10 | default: the default value 11 | - type: reference 12 | name: referenceSingleToNonDuplicatable 13 | models: [data_model_1] 14 | - type: reference 15 | name: referenceSingleToDuplicatable 16 | models: [data_model_2] 17 | -------------------------------------------------------------------------------- /packages/@contentlayer/experimental-source-files-stackbit/src/__test__/fixtures/kitchen-sink/.stackbit/models/object_model_1.yaml: -------------------------------------------------------------------------------- 1 | name: object_model_1 2 | type: object 3 | fields: 4 | - type: string 5 | name: string_field 6 | - type: string 7 | name: string_required 8 | required: true 9 | -------------------------------------------------------------------------------- /packages/@contentlayer/experimental-source-files-stackbit/src/__test__/fixtures/kitchen-sink/.stackbit/models/object_model_2.yaml: -------------------------------------------------------------------------------- 1 | name: object_model_2 2 | type: object 3 | fields: 4 | - type: string 5 | name: string_field 6 | - type: string 7 | name: string_default 8 | default: the default value 9 | -------------------------------------------------------------------------------- /packages/@contentlayer/experimental-source-files-stackbit/src/__test__/fixtures/kitchen-sink/.stackbit/models/page_model_1.yaml: -------------------------------------------------------------------------------- 1 | name: page_model_1 2 | type: page 3 | urlPath: "/{slug}" 4 | filePath: "{slug}.md" 5 | hideContent: true 6 | fields: 7 | - type: string 8 | name: string_field 9 | - type: string 10 | name: string_required 11 | required: true 12 | -------------------------------------------------------------------------------- /packages/@contentlayer/experimental-source-files-stackbit/src/__test__/fixtures/kitchen-sink/.stackbit/models/page_model_2.yaml: -------------------------------------------------------------------------------- 1 | name: page_model_2 2 | type: page 3 | urlPath: "/{slug}" 4 | filePath: "{slug}.md" 5 | hideContent: true 6 | fields: 7 | - type: string 8 | name: string_field 9 | - type: string 10 | name: string_default 11 | default: the default value 12 | -------------------------------------------------------------------------------- /packages/@contentlayer/experimental-source-files-stackbit/src/__test__/fixtures/kitchen-sink/stackbit.yaml: -------------------------------------------------------------------------------- 1 | stackbitVersion: ~0.5.0 2 | ssgName: nextjs 3 | cmsName: git 4 | nodeVersion: "16" 5 | dataDir: content/data 6 | pagesDir: content/pages 7 | pageLayoutKey: type 8 | assets: 9 | referenceType: static 10 | staticDir: public 11 | uploadDir: images 12 | publicPath: / 13 | presetReferenceBehavior: copyReference 14 | duplicatableModels: [data_model_2] 15 | -------------------------------------------------------------------------------- /packages/@contentlayer/experimental-source-files-stackbit/src/__test__/fixtures/next-starter/.stackbit/models/Button.yaml: -------------------------------------------------------------------------------- 1 | name: Button 2 | labelField: label 3 | fields: 4 | - type: string 5 | name: label 6 | default: Click Me 7 | required: true 8 | - type: string 9 | name: url 10 | label: URL 11 | default: / 12 | required: true 13 | - type: enum 14 | name: theme 15 | controlType: button-group 16 | label: Color Scheme 17 | default: primary 18 | options: 19 | - label: Primary 20 | value: primary 21 | - label: Secondary 22 | value: secondary 23 | -------------------------------------------------------------------------------- /packages/@contentlayer/experimental-source-files-stackbit/src/__test__/fixtures/next-starter/.stackbit/models/Card.yaml: -------------------------------------------------------------------------------- 1 | name: Card 2 | labelField: heading 3 | fields: 4 | - type: string 5 | name: heading 6 | default: Card Heading 7 | - type: markdown 8 | name: subheading 9 | default: Card description goes here ... 10 | - type: string 11 | name: url 12 | label: URL 13 | default: / 14 | -------------------------------------------------------------------------------- /packages/@contentlayer/experimental-source-files-stackbit/src/__test__/fixtures/next-starter/.stackbit/models/CardGridSection.yaml: -------------------------------------------------------------------------------- 1 | name: CardGridSection 2 | label: Card Grid 3 | labelField: heading 4 | groups: 5 | - SectionComponents 6 | fields: 7 | - type: string 8 | name: heading 9 | default: Card Grid Heading 10 | - type: markdown 11 | name: subheading 12 | default: Card Grid Subheading 13 | - type: list 14 | name: cards 15 | items: 16 | type: model 17 | models: [Card] 18 | -------------------------------------------------------------------------------- /packages/@contentlayer/experimental-source-files-stackbit/src/__test__/fixtures/next-starter/.stackbit/models/FooterConfig.yaml: -------------------------------------------------------------------------------- 1 | name: FooterConfig 2 | label: Footer Config 3 | labelField: body 4 | fields: 5 | - type: markdown 6 | name: body 7 | label: Footer Text 8 | -------------------------------------------------------------------------------- /packages/@contentlayer/experimental-source-files-stackbit/src/__test__/fixtures/next-starter/.stackbit/models/HeroSection.yaml: -------------------------------------------------------------------------------- 1 | name: HeroSection 2 | label: Hero 3 | labelField: heading 4 | groups: 5 | - SectionComponents 6 | fields: 7 | - type: string 8 | name: heading 9 | default: Hero Heading 10 | - type: markdown 11 | name: subheading 12 | default: Hero Subheading 13 | - type: list 14 | name: buttons 15 | items: 16 | type: model 17 | models: [Button] 18 | -------------------------------------------------------------------------------- /packages/@contentlayer/experimental-source-files-stackbit/src/__test__/fixtures/next-starter/.stackbit/models/Page.yaml: -------------------------------------------------------------------------------- 1 | name: Page 2 | hideContent: true 3 | fields: 4 | - type: string 5 | name: title 6 | default: This is a new page 7 | required: true 8 | - type: list 9 | name: sections 10 | items: 11 | type: model 12 | groups: [SectionComponents] 13 | -------------------------------------------------------------------------------- /packages/@contentlayer/experimental-source-files-stackbit/src/__test__/fixtures/next-starter/.stackbit/models/SiteConfig.yaml: -------------------------------------------------------------------------------- 1 | type: data 2 | name: SiteConfig 3 | label: Site Config 4 | singleInstance: true 5 | fields: 6 | - type: string 7 | name: title 8 | label: Site Title 9 | - type: model 10 | name: footer 11 | label: Footer Config 12 | models: [FooterConfig] 13 | -------------------------------------------------------------------------------- /packages/@contentlayer/experimental-source-files-stackbit/src/__test__/fixtures/next-starter/stackbit.yaml: -------------------------------------------------------------------------------- 1 | stackbitVersion: ~0.5.0 2 | cmsName: git 3 | ssgName: nextjs 4 | nodeVersion: '16' 5 | dataDir: content/data 6 | pagesDir: content/pages 7 | pageLayoutKey: type 8 | assets: 9 | referenceType: static 10 | staticDir: public 11 | uploadDir: images 12 | publicPath: / 13 | contentModels: 14 | Page: 15 | isPage: true 16 | urlPath: '/{slug}' 17 | newFilePath: '{slug}.md' 18 | -------------------------------------------------------------------------------- /packages/@contentlayer/experimental-source-files-stackbit/src/__test__/fixtures/small-business/.stackbit/models/CheckboxFormControl.yaml: -------------------------------------------------------------------------------- 1 | type: object 2 | name: CheckboxFormControl 3 | label: Checkbox 4 | labelField: label 5 | fieldGroups: 6 | - name: styles 7 | label: Styles 8 | icon: palette 9 | fields: 10 | - type: string 11 | name: name 12 | label: Name 13 | default: updates 14 | required: true 15 | - type: string 16 | name: label 17 | label: Label 18 | default: 'Sign me up to receive updates' 19 | - type: boolean 20 | name: isRequired 21 | label: Is the field required? 22 | default: false 23 | - type: enum 24 | name: width 25 | group: styles 26 | label: Width 27 | options: 28 | - label: Full 29 | value: full 30 | - label: 'One half' 31 | value: '1/2' 32 | default: full 33 | -------------------------------------------------------------------------------- /packages/@contentlayer/experimental-source-files-stackbit/src/__test__/fixtures/small-business/.stackbit/models/FeaturedPostsSection.yaml: -------------------------------------------------------------------------------- 1 | type: object 2 | name: FeaturedPostsSection 3 | label: Featured posts 4 | labelField: title 5 | thumbnail: https://assets.stackbit.com/components/models/thumbnails/default.png 6 | extends: 7 | - PostFeedSection 8 | groups: 9 | - sectionComponent 10 | fields: 11 | - name: title 12 | default: Featured 13 | - name: subtitle 14 | default: Featured blog posts section example 15 | - type: list 16 | name: posts 17 | label: Posts 18 | items: 19 | type: reference 20 | models: 21 | - PostLayout 22 | default: 23 | - content/pages/blog/post-three.md 24 | - content/pages/blog/post-two.md 25 | - content/pages/blog/post-one.md 26 | -------------------------------------------------------------------------------- /packages/@contentlayer/experimental-source-files-stackbit/src/__test__/fixtures/small-business/.stackbit/models/ImageBlock.yaml: -------------------------------------------------------------------------------- 1 | type: object 2 | name: ImageBlock 3 | label: Image 4 | labelField: altText 5 | fieldGroups: 6 | - name: settings 7 | label: Settings 8 | icon: gear 9 | fields: 10 | - type: image 11 | name: url 12 | label: Image 13 | default: https://assets.stackbit.com/components/images/default/default-image.png 14 | required: true 15 | - type: string 16 | name: altText 17 | label: Alt text 18 | description: Alternative text for screen readers 19 | default: altText of the image 20 | - type: string 21 | name: caption 22 | label: Caption 23 | default: Caption of the image 24 | - type: string 25 | name: elementId 26 | group: settings 27 | label: Element ID 28 | description: A unique ID for the HTML element. Must not contain whitespace. 29 | default: '' 30 | -------------------------------------------------------------------------------- /packages/@contentlayer/experimental-source-files-stackbit/src/__test__/fixtures/small-business/.stackbit/models/PagedPostsSection.yaml: -------------------------------------------------------------------------------- 1 | type: object 2 | name: PagedPostsSection 3 | label: Post feed 4 | labelField: title 5 | extends: 6 | - PostFeedSection 7 | fields: 8 | - name: title 9 | hidden: true 10 | default: null 11 | - name: subtitle 12 | hidden: true 13 | default: null 14 | - name: showDate 15 | default: true 16 | - name: showAuthor 17 | default: true 18 | - name: variant 19 | default: variant-a 20 | - name: actions 21 | hidden: true 22 | default: [] 23 | -------------------------------------------------------------------------------- /packages/@contentlayer/experimental-source-files-stackbit/src/__test__/fixtures/small-business/.stackbit/models/RecentPostsSection.yaml: -------------------------------------------------------------------------------- 1 | type: object 2 | name: RecentPostsSection 3 | label: Recent posts 4 | labelField: title 5 | extends: 6 | - PostFeedSection 7 | groups: 8 | - sectionComponent 9 | fields: 10 | - name: title 11 | default: Recent Posts 12 | - name: subtitle 13 | default: Latest blog posts section example 14 | - type: number 15 | name: recentCount 16 | label: Number of recent posts to show 17 | default: 6 18 | -------------------------------------------------------------------------------- /packages/@contentlayer/experimental-source-files-stackbit/src/__test__/fixtures/small-business/stackbit.yaml: -------------------------------------------------------------------------------- 1 | stackbitVersion: ~0.4.0 2 | ssgName: nextjs 3 | nodeVersion: '14' 4 | cmsName: git 5 | assets: 6 | referenceType: static 7 | staticDir: public 8 | uploadDir: images 9 | publicPath: / 10 | dataDir: content/data 11 | pagesDir: content/pages 12 | pageLayoutKey: layout 13 | objectTypeKey: type 14 | styleObjectModelName: ThemeStyle 15 | contentModels: 16 | PageLayout: 17 | isPage: true 18 | urlPath: '/{slug}' 19 | newFilePath: '{slug}.md' 20 | PostLayout: 21 | isPage: true 22 | urlPath: '/blog/{slug}' 23 | newFilePath: 'blog/{slug}.md' 24 | Person: 25 | newFilePath: 'team/{slug}.json' 26 | PostFeedLayout: 27 | isPage: true 28 | singleInstance: true 29 | urlPath: '/blog' 30 | file: 'blog/index.md' 31 | newFilePath: 'blog/index.md' 32 | modelsSource: 33 | type: files 34 | modelDirs: 35 | - .stackbit/models 36 | -------------------------------------------------------------------------------- /packages/@contentlayer/experimental-source-files-stackbit/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "module": "ES2020", 5 | "rootDir": "./src", 6 | "outDir": "./dist", 7 | "tsBuildInfoFile": "./dist/.tsbuildinfo.json" 8 | }, 9 | "include": ["./src"], 10 | "references": [{ "path": "../utils" }, { "path": "../source-files" }, { "path": "../core" }] 11 | } 12 | -------------------------------------------------------------------------------- /packages/@contentlayer/source-contentful/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@contentlayer/source-contentful", 3 | "version": "0.3.4", 4 | "type": "module", 5 | "exports": "./dist/index.js", 6 | "types": "./dist/index.d.ts", 7 | "files": [ 8 | "./dist/**/*.{js,ts,map}", 9 | "./src", 10 | "./package.json" 11 | ], 12 | "scripts": { 13 | "test": "echo No tests yet" 14 | }, 15 | "devDependencies": { 16 | "@types/node": "^20.3.2" 17 | }, 18 | "dependencies": { 19 | "@contentlayer/core": "workspace:*", 20 | "@contentlayer/utils": "workspace:*", 21 | "contentful-management": "7.22.4" 22 | }, 23 | "license": "MIT" 24 | } 25 | -------------------------------------------------------------------------------- /packages/@contentlayer/source-contentful/src/errors.ts: -------------------------------------------------------------------------------- 1 | import { errorToString } from '@contentlayer/utils' 2 | import { Tagged } from '@contentlayer/utils/effect' 3 | 4 | export class UnknownContentfulError extends Tagged('UnknownContentfulError')<{ readonly error: unknown }> { 5 | toString = () => `UnknownContentfulError: ${errorToString(this.error)}` 6 | } 7 | -------------------------------------------------------------------------------- /packages/@contentlayer/source-contentful/src/types.ts: -------------------------------------------------------------------------------- 1 | import * as Contentful from 'contentful-management/types' 2 | 3 | export { Contentful } 4 | 5 | export type RawDocumentData = { 6 | sys: Contentful.EntityMetaSysProps 7 | metadata: Contentful.MetadataProps 8 | } 9 | 10 | export type PluginOptions = { 11 | fieldOptions?: FieldOptions 12 | } 13 | 14 | export type FieldOptions = { 15 | /** 16 | * Name of the field containing the body/content extracted when `contentType` is `markdown` or `mdx`. 17 | * @default "body" 18 | */ 19 | bodyFieldName?: string 20 | /** 21 | * Name of the field containing the name of the document type (or nested document type). 22 | * @default "type" 23 | */ 24 | typeFieldName?: string 25 | } 26 | -------------------------------------------------------------------------------- /packages/@contentlayer/source-contentful/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "module": "ES2020", 5 | "rootDir": "./src", 6 | "outDir": "./dist", 7 | "tsBuildInfoFile": "./dist/.tsbuildinfo.json" 8 | }, 9 | "include": ["./src"], 10 | "references": [{ "path": "../utils" }, { "path": "../core" }] 11 | } 12 | -------------------------------------------------------------------------------- /packages/@contentlayer/source-files/src/__test__/fetchData/fixtures/3-small-files/a.md: -------------------------------------------------------------------------------- 1 | Hello world 2 | -------------------------------------------------------------------------------- /packages/@contentlayer/source-files/src/__test__/fetchData/fixtures/3-small-files/b.md: -------------------------------------------------------------------------------- 1 | --- 2 | --- 3 | 4 | Hello world 5 | -------------------------------------------------------------------------------- /packages/@contentlayer/source-files/src/__test__/fetchData/fixtures/misc-files/empty-json/empty.json: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/packages/@contentlayer/source-files/src/__test__/fetchData/fixtures/misc-files/empty-json/empty.json -------------------------------------------------------------------------------- /packages/@contentlayer/source-files/src/__test__/fetchData/fixtures/misc-files/empty-markdown/empty.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/packages/@contentlayer/source-files/src/__test__/fetchData/fixtures/misc-files/empty-markdown/empty.md -------------------------------------------------------------------------------- /packages/@contentlayer/source-files/src/__test__/fetchData/fixtures/misc-files/empty-mdx/empty.mdx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/packages/@contentlayer/source-files/src/__test__/fetchData/fixtures/misc-files/empty-mdx/empty.mdx -------------------------------------------------------------------------------- /packages/@contentlayer/source-files/src/__test__/fetchData/fixtures/misc-files/empty-yaml/empty.yaml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/packages/@contentlayer/source-files/src/__test__/fetchData/fixtures/misc-files/empty-yaml/empty.yaml -------------------------------------------------------------------------------- /packages/@contentlayer/source-files/src/__test__/mapping/getFlattenedPath.spec.ts: -------------------------------------------------------------------------------- 1 | import { expect, test } from 'vitest' 2 | 3 | import { getFlattenedPath } from '../../fetchData/mapping/index.js' 4 | 5 | test('getFlattenedPath', () => { 6 | expect(getFlattenedPath('some/path/doc.md')).toBe('some/path/doc') 7 | expect(getFlattenedPath('some/path/index.md')).toBe('some/path') 8 | expect(getFlattenedPath('some/index/index.md')).toBe('some/index') 9 | expect(getFlattenedPath('index/index.md')).toBe('index') 10 | expect(getFlattenedPath('index.md')).toBe('') 11 | expect(getFlattenedPath('some/sub/path/index.md')).toBe('some/sub/path') 12 | expect(getFlattenedPath('some/sub/path/some-file-with-index.md')).toBe('some/sub/path/some-file-with-index') 13 | }) 14 | -------------------------------------------------------------------------------- /packages/@contentlayer/source-files/src/fetchData/types.ts: -------------------------------------------------------------------------------- 1 | export type RawContent = RawContentMarkdown | RawContentMDX | RawContentJSON | RawContentYAML 2 | 3 | export interface RawContentMarkdown { 4 | readonly kind: 'markdown' 5 | fields: Record 6 | body: string 7 | rawDocumentContent: string 8 | } 9 | 10 | export interface RawContentMDX { 11 | readonly kind: 'mdx' 12 | fields: Record 13 | body: string 14 | rawDocumentContent: string 15 | } 16 | 17 | export interface RawContentJSON { 18 | readonly kind: 'json' 19 | fields: Record 20 | } 21 | 22 | export interface RawContentYAML { 23 | readonly kind: 'yaml' 24 | fields: Record 25 | } 26 | -------------------------------------------------------------------------------- /packages/@contentlayer/source-files/src/schema/defs/computed-field.ts: -------------------------------------------------------------------------------- 1 | import type { GetDocumentTypeMapGen } from '@contentlayer/core' 2 | 3 | import type { LocalDocument } from '../../types.js' 4 | import type { FieldDefType } from './index.js' 5 | 6 | export type ComputedField = { 7 | description?: string 8 | type: FieldDefType 9 | resolve: ComputedFieldResolver 10 | } 11 | 12 | // TODO come up with a way to hide computed fields from passed in document 13 | type ComputedFieldResolver = ( 14 | _: GetDocumentTypeGen, 15 | ) => any | Promise 16 | 17 | type GetDocumentTypeGen = Name extends keyof GetDocumentTypeMapGen 18 | ? GetDocumentTypeMapGen[Name] 19 | : LocalDocument 20 | 21 | // type GetDocumentTypeGen = GetDocumentTypeMapGen[Name] 22 | -------------------------------------------------------------------------------- /packages/@contentlayer/source-files/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "module": "ES2020", 5 | "rootDir": "./src", 6 | "outDir": "./dist", 7 | "tsBuildInfoFile": "./dist/.tsbuildinfo.json" 8 | }, 9 | "include": ["./src"], 10 | "references": [{ "path": "../utils" }, { "path": "../core" }] 11 | } 12 | -------------------------------------------------------------------------------- /packages/@contentlayer/source-remote-files/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@contentlayer/source-remote-files", 3 | "version": "0.3.4", 4 | "type": "module", 5 | "exports": { 6 | ".": { 7 | "import": "./dist/index.js" 8 | } 9 | }, 10 | "types": "./dist/index.d.ts", 11 | "files": [ 12 | "./dist/*.{js,ts,map}", 13 | "./dist/!(__test__)/**/*.{js,ts,map}", 14 | "./src", 15 | "./package.json" 16 | ], 17 | "dependencies": { 18 | "@contentlayer/core": "workspace:*", 19 | "@contentlayer/source-files": "workspace:*", 20 | "@contentlayer/utils": "workspace:*" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /packages/@contentlayer/source-remote-files/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "module": "ES2020", 5 | "rootDir": "./src", 6 | "outDir": "./dist", 7 | "tsBuildInfoFile": "./dist/.tsbuildinfo.json" 8 | }, 9 | "include": ["./src"], 10 | "references": [{ "path": "../source-files" }, { "path": "../utils" }, { "path": "../core" }] 11 | } 12 | -------------------------------------------------------------------------------- /packages/@contentlayer/utils/node.js: -------------------------------------------------------------------------------- 1 | module.exports = require('./dist/cjs/node') 2 | -------------------------------------------------------------------------------- /packages/@contentlayer/utils/src/effect/Array.ts: -------------------------------------------------------------------------------- 1 | import { Array, pipe } from '@effect-ts/core' 2 | 3 | import * as O from './Option.js' 4 | 5 | export * from '@effect-ts/core/Collections/Immutable/Array' 6 | 7 | export const headUnsafe = (array: Array.Array): A => pipe(array, Array.head, O.getUnsafe) 8 | -------------------------------------------------------------------------------- /packages/@contentlayer/utils/src/effect/Option.ts: -------------------------------------------------------------------------------- 1 | import { Option } from '@effect-ts/core' 2 | 3 | export * from '@effect-ts/core/Option' 4 | 5 | export const getUnsafe = (option: Option.Option): A => { 6 | if (Option.isSome(option)) { 7 | return option.value 8 | } 9 | 10 | throw new Error('Option.getUnsafe: Option is None') 11 | } 12 | -------------------------------------------------------------------------------- /packages/@contentlayer/utils/src/effect/Tracing/Enable.ts: -------------------------------------------------------------------------------- 1 | import '@effect-ts/core/Tracing/Enable' 2 | -------------------------------------------------------------------------------- /packages/@contentlayer/utils/src/fs.ts: -------------------------------------------------------------------------------- 1 | export * as fs from './fs_.js' 2 | -------------------------------------------------------------------------------- /packages/@contentlayer/utils/src/guards.ts: -------------------------------------------------------------------------------- 1 | export const isNotUndefined = (_: T | undefined): _ is T => _ !== undefined 2 | export const isUndefined = (_: T | undefined): _ is undefined => _ === undefined 3 | -------------------------------------------------------------------------------- /packages/@contentlayer/utils/src/hash.ts: -------------------------------------------------------------------------------- 1 | import { xxhash64 } from 'hash-wasm' 2 | import type { JsonValue } from 'type-fest' 3 | 4 | import { T, Tagged } from './effect/index.js' 5 | 6 | export const hashObject = (obj: JsonValue | any): T.Effect => { 7 | return T.tryCatchPromise( 8 | () => xxhash64(stringifyIfNeeded(obj)), 9 | (error) => new HashError({ error }), 10 | ) 11 | } 12 | 13 | export class HashError extends Tagged('HashError')<{ 14 | readonly error: unknown 15 | }> {} 16 | 17 | const stringifyIfNeeded = (_: JsonValue | any) => (typeof _ === 'string' ? _ : JSON.stringify(_)) 18 | -------------------------------------------------------------------------------- /packages/@contentlayer/utils/src/node/index.ts: -------------------------------------------------------------------------------- 1 | export * from './version.js' 2 | 3 | export * from './fs.js' 4 | export * as FSWatch from './fs-watcher.js' 5 | -------------------------------------------------------------------------------- /packages/@contentlayer/utils/src/object/omit.ts: -------------------------------------------------------------------------------- 1 | // type ConvertUndefined = OrUndefined<{ [K in keyof T as undefined extends T[K] ? K : never]-?: T[K] }> 2 | // type OrUndefined = { [K in keyof T]: T[K] | undefined } 3 | // type PickRequired = { [K in keyof T as undefined extends T[K] ? never : K]: T[K] } 4 | // type ConvertPick = ConvertUndefined & PickRequired 5 | 6 | /** Returns a shallowly cloned object with the provided keys omitted */ 7 | export const omit = (obj: Obj, keys: Keys[]): Omit => { 8 | return Object.keys(obj).reduce((acc, key: any) => { 9 | if (!keys.includes(key)) { 10 | acc[key] = (obj as any)[key] 11 | } 12 | return acc 13 | }, {} as any) 14 | } 15 | -------------------------------------------------------------------------------- /packages/@contentlayer/utils/src/object/pick.ts: -------------------------------------------------------------------------------- 1 | type ConvertUndefined = OrUndefined<{ [K in keyof T as undefined extends T[K] ? K : never]-?: T[K] }> 2 | type OrUndefined = { [K in keyof T]: T[K] | undefined } 3 | type PickRequired = { [K in keyof T as undefined extends T[K] ? never : K]: T[K] } 4 | type ConvertPick = ConvertUndefined & PickRequired 5 | 6 | export const pick = ( 7 | obj: Obj, 8 | keys: Keys[], 9 | /** Whether to filter out explicit `undefined` values */ 10 | filterUndefined = true, 11 | ): ConvertPick<{ [K in Keys]: Obj[K] }> => { 12 | return keys.reduce((acc, key) => { 13 | const val = obj[key] 14 | if (val === undefined && filterUndefined) return acc 15 | 16 | acc[key] = val 17 | 18 | return acc 19 | }, {} as any) 20 | } 21 | -------------------------------------------------------------------------------- /packages/@contentlayer/utils/src/single-item.ts: -------------------------------------------------------------------------------- 1 | export class SingleItem { 2 | constructor(public item: T) {} 3 | 4 | map(fn: (item: T) => U): SingleItem { 5 | return new SingleItem(fn(this.item)) 6 | } 7 | 8 | filter(fn: (item: T) => boolean): SingleItem { 9 | return fn(this.item) ? this : new SingleItem(undefined) 10 | } 11 | } 12 | 13 | export const singleItem = (item: T) => new SingleItem(item) 14 | -------------------------------------------------------------------------------- /packages/@contentlayer/utils/src/string.ts: -------------------------------------------------------------------------------- 1 | export const lowercaseFirstChar = (str: string) => str.charAt(0).toLowerCase() + str.slice(1) 2 | export const uppercaseFirstChar = (str: string) => str.charAt(0).toUpperCase() + str.slice(1) 3 | -------------------------------------------------------------------------------- /packages/@contentlayer/utils/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tsconfig.base.json", 3 | "compilerOptions": { 4 | // Needed for `inflection` 5 | "allowSyntheticDefaultImports": true, 6 | "module": "ES2020", 7 | "rootDir": "./src", 8 | "outDir": "./dist", 9 | "tsBuildInfoFile": "./dist/.tsbuildinfo.json" 10 | }, 11 | "include": ["./src"], 12 | "references": [] 13 | } 14 | -------------------------------------------------------------------------------- /packages/archive/source-sanity/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@contentlayer/source-sanity", 3 | "version": "0.2.6", 4 | "type": "module", 5 | "exports": "./dist/index.js", 6 | "types": "./dist/index.d.ts", 7 | "files": [ 8 | "./dist/**/*.{js,ts,map}", 9 | "./src", 10 | "./package.json" 11 | ], 12 | "scripts": { 13 | "test": "echo No tests yet" 14 | }, 15 | "devDependencies": { 16 | "@types/node": "^17.0.45" 17 | }, 18 | "dependencies": { 19 | "@contentlayer/core": "workspace:*", 20 | "@contentlayer/utils": "workspace:*", 21 | "@sanity/client": "^2.10.5", 22 | "@sanity/core": "^2.10.5", 23 | "@sanity/image-url": "^0.140.22", 24 | "@sanity/schema": "^2.10.0", 25 | "rxjs": "^7.1.0" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /packages/archive/source-sanity/src/types.ts: -------------------------------------------------------------------------------- 1 | export type PluginOptions = { 2 | fieldOptions?: FieldOptions 3 | } 4 | 5 | export type FieldOptions = { 6 | /** 7 | * Name of the field containing the body/content extracted when `contentType` is `markdown` or `mdx`. 8 | * @default "body" 9 | */ 10 | bodyFieldName?: string 11 | /** 12 | * Name of the field containing the name of the document type (or nested document type). 13 | * @default "type" 14 | */ 15 | typeFieldName?: string 16 | } 17 | -------------------------------------------------------------------------------- /packages/archive/source-sanity/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tsconfig.base.json", 3 | "compilerOptions": { 4 | // Needed for @sanity/image-url 5 | "allowSyntheticDefaultImports": true, 6 | // DOM needed for @sanity/client 7 | "lib": ["DOM", "ES2020"], 8 | "module": "ES2020", 9 | "rootDir": "./src", 10 | "outDir": "./dist", 11 | "tsBuildInfoFile": "./dist/.tsbuildinfo.json" 12 | }, 13 | "include": ["./src"], 14 | "references": [{ "path": "../core" }, { "path": "../utils" }] 15 | } 16 | -------------------------------------------------------------------------------- /packages/contentful-generator/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "contentful-generator", 3 | "private": true, 4 | "scripts": { 5 | "dev": "ts-node --transpile-only --compiler-options '{\"module\":\"CommonJS\"}' ./src/index.ts" 6 | }, 7 | "devDependencies": { 8 | "ts-node": "^10.9.1" 9 | }, 10 | "dependencies": { 11 | "contentful-management": "7.22.4", 12 | "contentful-migration": "^4.2.3", 13 | "lorem-ipsum": "^2.0.8" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /packages/contentful-generator/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "rootDir": "./src", 5 | "outDir": "./dist/types" 6 | }, 7 | "include": ["./src"] 8 | } 9 | -------------------------------------------------------------------------------- /packages/contentlayer-stackbit-yaml-generator/bin/cli.cjs: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | const main = async () => { 4 | const { run } = await import('../dist/cli') 5 | await run() 6 | } 7 | 8 | main().catch((e) => console.log(e)) 9 | -------------------------------------------------------------------------------- /packages/contentlayer-stackbit-yaml-generator/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "contentlayer-stackbit-yaml-generator", 3 | "version": "0.3.4", 4 | "type": "module", 5 | "bin": "./dist/cli/index.js", 6 | "exports": "./dist/lib/index.js", 7 | "types": "./dist/lib/index.d.ts", 8 | "files": [ 9 | "./dist/*.{js,ts,map}", 10 | "./dist/!(__test__)/**/*.{js,ts,map}", 11 | "./src", 12 | "./package.json" 13 | ], 14 | "scripts": { 15 | "test": "FORCE_COLOR=1 vitest" 16 | }, 17 | "dependencies": { 18 | "@contentlayer/core": "workspace:*", 19 | "@contentlayer/utils": "workspace:*", 20 | "@stackbit/sdk": "^0.3.25", 21 | "clipanion": "^3.2.1", 22 | "typanion": "3.12.1", 23 | "yaml": "^2.3.1" 24 | }, 25 | "devDependencies": { 26 | "contentlayer": "workspace:*", 27 | "typescript": "^5.1.6", 28 | "vite": "^4.3.1", 29 | "vitest": "0.30.1" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /packages/contentlayer-stackbit-yaml-generator/src/__test__/convert.spec.ts: -------------------------------------------------------------------------------- 1 | import { expect, test } from 'vitest' 2 | 3 | import { convertSchema } from '../cli/convert.js' 4 | import { toYamlString } from '../cli/utils.js' 5 | import * as fixtures from './fixtures/index.js' 6 | 7 | test('azimuth schema', async () => { 8 | const coreSchema = await fixtures.makeAzimuthSchema() 9 | expect(coreSchema).toMatchSnapshot() 10 | const stackbitConfig = toYamlString(convertSchema(coreSchema, {})) 11 | expect(stackbitConfig).toMatchSnapshot() 12 | }) 13 | 14 | test('blog schema', async () => { 15 | const coreSchema = await fixtures.makeBlogSchema() 16 | expect(coreSchema).toMatchSnapshot() 17 | const stackbitConfig = toYamlString(convertSchema(coreSchema, {})) 18 | expect(stackbitConfig).toMatchSnapshot() 19 | }) 20 | -------------------------------------------------------------------------------- /packages/contentlayer-stackbit-yaml-generator/src/__test__/fixtures/azimuth-schema/documents/Person.ts: -------------------------------------------------------------------------------- 1 | import { defineDocumentType } from 'contentlayer/source-files' 2 | 3 | export const Person = defineDocumentType(() => ({ 4 | name: 'Person', 5 | filePathPattern: 'data/authors/*.yaml', 6 | fields: { 7 | first_name: { type: 'string' }, 8 | last_name: { type: 'string' }, 9 | bio: { type: 'markdown' }, 10 | photo: { type: 'string' }, 11 | }, 12 | extensions: { 13 | stackbit: { folder: 'authors' }, 14 | }, 15 | })) 16 | -------------------------------------------------------------------------------- /packages/contentlayer-stackbit-yaml-generator/src/__test__/fixtures/azimuth-schema/index.ts: -------------------------------------------------------------------------------- 1 | export { Blog } from './documents/Blog.js' 2 | export { Config } from './documents/Config.js' 3 | export { Landing } from './documents/Landing.js' 4 | export { Page } from './documents/Page.js' 5 | export { Person } from './documents/Person.js' 6 | export { Post } from './documents/Post.js' 7 | -------------------------------------------------------------------------------- /packages/contentlayer-stackbit-yaml-generator/src/__test__/fixtures/azimuth-schema/utils.ts: -------------------------------------------------------------------------------- 1 | import type { DocumentGen } from 'contentlayer/core' 2 | 3 | export const urlFromFilePath = (doc: DocumentGen): string => doc._raw.flattenedPath.replace(/pages\/?/, '') 4 | -------------------------------------------------------------------------------- /packages/contentlayer-stackbit-yaml-generator/src/__test__/fixtures/blog-schema/index.ts: -------------------------------------------------------------------------------- 1 | import { defineDocumentType } from 'contentlayer/source-files' 2 | 3 | export const post = defineDocumentType(() => ({ 4 | name: 'Post', 5 | filePathPattern: `**/*.md`, 6 | fields: { 7 | title: { 8 | type: 'string', 9 | description: 'The title of the post', 10 | required: true, 11 | }, 12 | date: { 13 | type: 'date', 14 | description: 'The date of the post', 15 | required: true, 16 | }, 17 | }, 18 | computedFields: { 19 | slug: { type: 'string', resolve: (_) => _._id.replace('.md', '') }, 20 | }, 21 | })) 22 | -------------------------------------------------------------------------------- /packages/contentlayer-stackbit-yaml-generator/src/cli/index.ts: -------------------------------------------------------------------------------- 1 | import { Builtins, Cli } from 'clipanion' 2 | 3 | import { DefaultCommand } from './DefaultCommand.js' 4 | 5 | export const run = async () => { 6 | const [node, app, ...args] = process.argv 7 | 8 | const cli = new Cli({ 9 | binaryLabel: `My Application`, 10 | binaryName: `${node} ${app}`, 11 | binaryVersion: `1.0.1`, 12 | }) 13 | 14 | cli.register(DefaultCommand) 15 | cli.register(Builtins.HelpCommand) 16 | cli.register(Builtins.VersionCommand) 17 | 18 | await cli.runExit(args, Cli.defaultContext) 19 | } 20 | -------------------------------------------------------------------------------- /packages/contentlayer-stackbit-yaml-generator/src/cli/utils.ts: -------------------------------------------------------------------------------- 1 | import YAML from 'yaml' 2 | 3 | export const toYamlString = (json: any): string => YAML.stringify(json) 4 | -------------------------------------------------------------------------------- /packages/contentlayer-stackbit-yaml-generator/src/lib/index.ts: -------------------------------------------------------------------------------- 1 | import type * as StackbitTypes from '@stackbit/types' 2 | 3 | export type Transform = (config: StackbitTypes.StackbitConfig) => StackbitTypes.StackbitConfig 4 | 5 | export const defineTransform = (transform: Transform): Transform => transform 6 | -------------------------------------------------------------------------------- /packages/contentlayer-stackbit-yaml-generator/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "module": "ES2020", 5 | "rootDir": "./src", 6 | "outDir": "./dist", 7 | "tsBuildInfoFile": "./dist/.tsbuildinfo.json" 8 | }, 9 | "include": ["./src"], 10 | "references": [ 11 | { "path": "../@contentlayer/utils" }, 12 | { "path": "../contentlayer" }, 13 | { "path": "../@contentlayer/core" } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /packages/contentlayer/bin/cli.cjs: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | const main = async () => { 4 | const { run } = await import('@contentlayer/cli') 5 | await run() 6 | } 7 | 8 | main().catch((e) => console.log(e)) 9 | -------------------------------------------------------------------------------- /packages/contentlayer/index.d.ts: -------------------------------------------------------------------------------- 1 | // needed for Next.js to work 2 | -------------------------------------------------------------------------------- /packages/contentlayer/src/client/index.ts: -------------------------------------------------------------------------------- 1 | export * from '@contentlayer/client' 2 | -------------------------------------------------------------------------------- /packages/contentlayer/src/core/index.ts: -------------------------------------------------------------------------------- 1 | export * from '@contentlayer/core' 2 | -------------------------------------------------------------------------------- /packages/contentlayer/src/source-files/index.ts: -------------------------------------------------------------------------------- 1 | export * from '@contentlayer/source-files' 2 | -------------------------------------------------------------------------------- /packages/contentlayer/src/source-files/schema/index.ts: -------------------------------------------------------------------------------- 1 | export * from '@contentlayer/source-files/schema/defs' 2 | -------------------------------------------------------------------------------- /packages/contentlayer/src/source-remote-files/index.ts: -------------------------------------------------------------------------------- 1 | export * from '@contentlayer/source-remote-files' 2 | -------------------------------------------------------------------------------- /packages/contentlayer/src/utils/index.ts: -------------------------------------------------------------------------------- 1 | export * from '@contentlayer/utils' 2 | -------------------------------------------------------------------------------- /packages/contentlayer/src/utils/node/index.ts: -------------------------------------------------------------------------------- 1 | export * from '@contentlayer/utils/node' 2 | -------------------------------------------------------------------------------- /packages/contentlayer/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "module": "ES2020", 5 | "rootDir": "./src", 6 | "outDir": "./dist", 7 | "tsBuildInfoFile": "./dist/.tsbuildinfo.json" 8 | }, 9 | "include": ["./src"], 10 | "references": [ 11 | { "path": "../@contentlayer/cli" }, 12 | { "path": "../@contentlayer/client" }, 13 | { "path": "../@contentlayer/source-files" }, 14 | { "path": "../@contentlayer/source-remote-files" }, 15 | { "path": "../@contentlayer/utils" }, 16 | { "path": "../@contentlayer/core" } 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /packages/integration-tests/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "integration-tests", 3 | "private": true, 4 | "type": "module", 5 | "scripts": { 6 | "test": "FORCE_COLOR=1 vitest" 7 | }, 8 | "devDependencies": { 9 | "contentlayer": "workspace:*", 10 | "remark-mdx-images": "^2.0.0", 11 | "typescript": "^5.1.6", 12 | "vite": "^4.3.1", 13 | "vitest": "0.12.10" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /packages/integration-tests/src/empty-content-folder/posts/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/packages/integration-tests/src/empty-content-folder/posts/.gitkeep -------------------------------------------------------------------------------- /packages/integration-tests/src/image-field/content/posts/image-a.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/packages/integration-tests/src/image-field/content/posts/image-a.png -------------------------------------------------------------------------------- /packages/integration-tests/src/image-field/content/posts/post-a.md: -------------------------------------------------------------------------------- 1 | --- 2 | coverImage: ./image-a.png 3 | --- 4 | 5 | # Hello world 6 | -------------------------------------------------------------------------------- /packages/integration-tests/src/markdown/posts/post-1.md: -------------------------------------------------------------------------------- 1 | # Hello world 2 | -------------------------------------------------------------------------------- /packages/integration-tests/src/mdx-remark-images/content/posts/image-a.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/packages/integration-tests/src/mdx-remark-images/content/posts/image-a.png -------------------------------------------------------------------------------- /packages/integration-tests/src/mdx-remark-images/content/posts/post-a.mdx: -------------------------------------------------------------------------------- 1 | # Hello world 2 | 3 | ![test](./image-a.png) 4 | -------------------------------------------------------------------------------- /packages/integration-tests/src/mdx-remark-images/contentDirPath/posts/image-b.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/contentlayerdev/contentlayer/27bfc5a8b98234b0380ebd33c3de06c383d932f8/packages/integration-tests/src/mdx-remark-images/contentDirPath/posts/image-b.png -------------------------------------------------------------------------------- /packages/integration-tests/src/mdx-remark-images/contentDirPath/posts/post-b.mdx: -------------------------------------------------------------------------------- 1 | # Hello world 2 | 3 | ![test](./posts/image-b.png) 4 | -------------------------------------------------------------------------------- /packages/integration-tests/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "module": "ES2020", 5 | "rootDir": "./src", 6 | "outDir": "./dist", 7 | "tsBuildInfoFile": "./dist/.tsbuildinfo.json" 8 | }, 9 | "include": ["./src"], 10 | "references": [ 11 | { "path": "../@contentlayer/utils" }, 12 | { "path": "../contentlayer" }, 13 | { "path": "../@contentlayer/core" } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /packages/integration-tests/vitest.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vitest/config' 2 | 3 | export default defineConfig({ 4 | test: { 5 | // See README.md for more information why this is needed 6 | threads: false, 7 | }, 8 | }) 9 | -------------------------------------------------------------------------------- /packages/next-contentlayer/src/ambient.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'next/dist/client/dev/error-overlay/eventsource.js' 2 | -------------------------------------------------------------------------------- /packages/next-contentlayer/src/hooks/index.ts: -------------------------------------------------------------------------------- 1 | export * from './useLiveReload.js' 2 | export * from './useMDXComponent.js' 3 | -------------------------------------------------------------------------------- /packages/next-contentlayer/src/hooks/jsx-runtime.cjs: -------------------------------------------------------------------------------- 1 | const _jsx_runtime = require('react/jsx-runtime') 2 | 3 | module.exports._jsx_runtime = _jsx_runtime 4 | -------------------------------------------------------------------------------- /packages/next-contentlayer/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "compilerOptions": { 4 | // needed for Next.js imports 5 | "allowSyntheticDefaultImports": true, 6 | "module": "ES2020", 7 | "rootDir": "./src", 8 | "outDir": "./dist", 9 | "tsBuildInfoFile": "./dist/.tsbuildinfo.json" 10 | }, 11 | "include": ["./src"], 12 | "references": [{ "path": "../@contentlayer/utils" }, { "path": "../@contentlayer/core" }] 13 | } 14 | -------------------------------------------------------------------------------- /prettier.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | printWidth: 120, 3 | semi: false, 4 | trailingComma: 'all', 5 | singleQuote: true, 6 | } 7 | -------------------------------------------------------------------------------- /tsconfig.all.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.base.json", 3 | "compilerOptions": {}, 4 | "include": [], 5 | "references": [ 6 | { "path": "./packages/@contentlayer/cli" }, 7 | { "path": "./packages/@contentlayer/core" }, 8 | { "path": "./packages/@contentlayer/source-contentful" }, 9 | { "path": "./packages/@contentlayer/source-files" }, 10 | { "path": "./packages/@contentlayer/experimental-source-files-stackbit" }, 11 | { "path": "./packages/@contentlayer/utils" }, 12 | { "path": "./packages/contentlayer" }, 13 | { "path": "./packages/contentlayer-stackbit-yaml-generator" }, 14 | { "path": "./packages/next-contentlayer" } 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /vercel.json: -------------------------------------------------------------------------------- 1 | { 2 | "github": { 3 | "silent": true 4 | } 5 | } 6 | --------------------------------------------------------------------------------