Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support SvelteKit #170

Open
seancdavis opened this issue Apr 8, 2022 · 9 comments
Open

Support SvelteKit #170

seancdavis opened this issue Apr 8, 2022 · 9 comments

Comments

@seancdavis
Copy link
Collaborator

Add your vote for SvelteKit support by clicking the 👍 emoji below.

@stale
Copy link

stale bot commented Jun 7, 2022

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@nisarhassan12
Copy link

Thanks to all the contributors for their great work on this project. I was wondering how many more votes is it gonna need before it gets worked on?

@vimfn
Copy link

vimfn commented Jul 13, 2023

Sveltekit support will be much appreciated 😄 !!

@seancdavis
Copy link
Collaborator Author

Tight integration with SvelteKit is not currently planned. However, you can still use Contentlayer with SvelteKit.

I've done this with other frameworks that aren't officially supported. It usually looks like this:

  1. Use a tool like concurrently to run contentlayer dev and the dev server in parallel.
  2. Run contentlayer build prior to running the framework's build command.

@git-no
Copy link

git-no commented Aug 6, 2023

I could create a working demo of a Sveltekit - Contentlayer - MDX integration with simple and little code.

For those interested here is the git repositiory: sveltekit-contentlayer-example

I hope this supports the Contentlayer project and helps to enlarge the Svelte / Contentlayer community.

@Ahidada
Copy link

Ahidada commented Aug 28, 2023

I could create a working demo of a Sveltekit - Contentlayer - MDX integration with simple and little code.

For those interested here is the git repositiory: sveltekit-contentlayer-example

I hope this supports the Contentlayer project and helps to enlarge the Svelte / Contentlayer community.

Can parse md, but SvelteKit doesn't have enough support for mdx

@git-no
Copy link

git-no commented Oct 22, 2023

@Ahidada

Can parse md, but SvelteKit doesn't have enough support for mdx

Quite an allegation. Maybe you can elaborate what support you are missing.

@soup-po
Copy link

soup-po commented Feb 18, 2024

yes please

@ap0nia
Copy link

ap0nia commented Mar 27, 2024

I could create a working demo of a Sveltekit - Contentlayer - MDX integration with simple and little code.

For those interested here is the git repositiory: sveltekit-contentlayer-example

I hope this supports the Contentlayer project and helps to enlarge the Svelte / Contentlayer community.

Given a repository that's prepared to import/render the contentlayer content, would a Vite plugin work? All it does is invoke contentlayer build and contentlayer dev during the Vite lifecycle.

// vite.config.js
// @ts-check

import * as core from '@contentlayer/core'
import { fs, errorToString } from '@contentlayer/utils'
import { E, OT, pipe, S, T } from '@contentlayer/utils/effect'
import { sveltekit } from '@sveltejs/kit/vite'
import { defineConfig } from 'vite'

export default defineConfig({
  plugins: [
    sveltekit(),
    contentlayer(),
  ],
})

/**
 * @typedef {{
 * clearCache?: boolean
 * configPath?: string | undefined
 * verbose?: boolean
 * isDev?: boolean
 * contentDirPath?: string
 * generatedDirPath?: string
 * }} ContentlayerOptions
 */

/**
 * Contentlayer Vite plugin.
 * @param {ContentlayerOptions?} options
 * @returns {import('vite').Plugin}
 */
function contentlayer(options = null) {
  const resolvedOptions = {
    generatedDirPath: '.contentlayer',
    contentDirPath: 'content',
    clearCache: false,
    configPath: undefined,
    verbose: false,
    isDev: true,
    ...options,
  }

  /**
   * @type {ReturnType<typeof startContentlayerDevelopmentWatch>}
   */
  let contentLayerWatcher

  /**
   * @see https://github.com/contentlayerdev/contentlayer/blob/main/packages/%40contentlayer/cli/src/commands/DevCommand.ts
   */
  const startContentlayerDevelopmentWatch = async () => {
    /**
     * Promise that runs in the background while the server is running.
     * TODO: terminate gracefully when the server is stopped.
     */
    pipe(
      pipe(
        S.fromEffect(
          T.gen(function*($) {
            if (resolvedOptions.clearCache) {
              const cwd = yield* $(core.getCwd)
              const artifactsDir = core.ArtifactsDir.getDirPath({ cwd })
              yield* $(fs.rm(artifactsDir, { recursive: true, force: true }))
              yield* $(T.log('Cache cleared successfully'))
            }
          }),
        ),
        S.chain(() => core.getConfigWatch({ configPath: resolvedOptions.configPath })),
        S.tapSkipFirstRight(() =>
          T.log(`Contentlayer config change detected. Updating type definitions and data...`),
        ),
        S.tapRight((config) =>
          config.source.options.disableImportAliasWarning ? T.unit : T.fork(core.validateTsconfig),
        ),
        S.chainSwitchMapEitherRight((config) =>
          core.generateDotpkgStream({
            config,
            verbose: resolvedOptions.verbose,
            isDev: resolvedOptions.isDev,
          }),
        ),
        S.tap(E.fold((error) => T.log(errorToString(error)), core.logGenerateInfo)),
        OT.withStreamSpan('@contentlayer/cli/commands/DevCommand:stream'),
        S.runDrain,
        OT.withSpan('@contentlayer/cli/commands/DevCommand:executeSafe'),
      ),
      core.runMain({
        tracingServiceName: 'contentlayer-cli',
        verbose: resolvedOptions.verbose || process.env['CL_DEBUG'] !== undefined,
      }),
    )
  }

  /**
   * @see https://github.com/contentlayerdev/contentlayer/blob/main/packages/%40contentlayer/cli/src/commands/BuildCommand.ts
   */
  const buildContentlayer = async () => {
    return pipe(
      pipe(
        T.gen(function*($) {
          if (resolvedOptions.clearCache) {
            const cwd = yield* $(core.getCwd)
            const artifactsDir = core.ArtifactsDir.getDirPath({ cwd })
            yield* $(fs.rm(artifactsDir, { recursive: true, force: true }))
            yield* $(T.log('Cache cleared successfully'))
          }
        }),
        T.chain(() => core.getConfig({ configPath: resolvedOptions.configPath })),
        T.tap((config) =>
          config.source.options.disableImportAliasWarning ? T.unit : T.fork(core.validateTsconfig),
        ),
        T.chain((config) => core.generateDotpkg({ config, verbose: resolvedOptions.verbose })),
        T.tap(core.logGenerateInfo),
        OT.withSpan('@contentlayer/cli/commands/BuildCommand:executeSafe'),
      ),
      core.runMain({
        tracingServiceName: 'contentlayer-cli',
        verbose: resolvedOptions.verbose || process.env['CL_DEBUG'] !== undefined,
      }),
    )
  }

  return {
    name: 'vite-plugin-contentlayer',

    /**
     * Add additional directories to the Vite server's file serving list.
     */
    async config() {
      return {
        server: {
          fs: {
            allow: [resolvedOptions.contentDirPath, resolvedOptions.generatedDirPath],
          },
        },
      }
    },

    /**
     * When development server starts, start contentlayer development watch.
     */
    async configureServer() {
      contentLayerWatcher = startContentlayerDevelopmentWatch()
    },

    /**
     * When build starts, build contentlayer.
     */
    async buildStart() {
      await buildContentlayer()
    },

    /**
     * TODO: When build ends, stop the contentlayer development watch.
     */
    async buildEnd() {
      if (contentLayerWatcher !== undefined) {
        contentLayerWatcher
      }
    },
  }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants