souporserious / next-dx

Enhance Next.js development with utilities for local and remote content.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

⚠️ Currently under development, not ready for use yet

This library is currently unstable and the API is in flux. It is being worked on in the open for better exposure, please feel free to file an issue if you have any questions or suggestions. As of right now, packages aren't published yet and documentation may be lacking or stale.

next-dx

Enhance Next.js development with utilities for local and remote content.

Features

♻️ Fast Refresh Remote Data

🗺 Generate Page Map

↔️ Navigation Links

📝 Normalize MDX Authoring

🧩 Extract TypeScript Types

Usage

const withNextDX = require('next-dx')({
  remarkPlugins: [], // runs on internal/external data md/mdx sources
  // watches and fast refreshes changed files
  // exposes meta information to utility functions
  files: [
    {
      name: 'components',
      entry: '../packages/package/components',
      exclude: '**/tests',
    },
    {
      name: 'hooks',
      entry: '../packages/package/hooks',
      exclude: '**/stories',
    },
  ],
})

module.exports = withNextDX({
  pageExtensions: ['.ts', '.tsx', '.mdx'],
})
import { getPages, getRoutes, getTypes } from 'next-dx'

function ComponentDoc({ pages, components, types, MDX }) {
  return <MDX />
}

export async function getStaticProps() {
  const { activeRoute, previousRoute, nextRoute } = getRoutes('components') // get top-level and sub routes
  const pages = await getPages() // get meta about all inernal and external pages
  const components = await getPages('components', 'slug') // get specific pages
  const types = await getTypes(components) // get TypeScript type information
  return {
    pages,
    components,
    types,
  }
}

♻️ Fast Refresh Remote Data

In your app file add the included hook to enable Fast Refresh for remote data:

import { useRemoteRefresh } from 'next-dx'

export default function App({ Component, pageProps }) {
  useRemoteRefresh()
  return <Component {...pageProps} />
}

🗺 Generate Page Map

Generate a map of all pages used throughout your app:

import { getPages } from 'next-dx'

export default function Index() {
  return <div>{flatMapPages(pages)}</div>
}

export function getStaticProps() {
  const pages = getPages()
  return {
    props: pages,
  }
}

Target specific pages:

const pages = getPages()

As well as static remote sources:

const pages = getPages('components/Avatar')

Optionally pass additional options to ignore:

const pages = getPages('components/Avatar', { ignore: 'tests' })

📝 Normalize MDX authoring

Use the same components and plugins for your MDX content:

const withNextDX = require('next-dx')({
  files: [
    {
      name: 'componentDocs',
      entry: '../packages/package/components/**/*.mdx',
    },
  ],
  remarkPlugins: [require('remark-gfm')],
})

module.exports = withNextDX({
  pageExtensions: ['.mdx'],
})

↔️ Navigation Links

Generate links for specific pages:

import { getRoutes } from 'next-dx'
import Link from 'next/link'

export default function Index({ posts, routes }) {
  return (
    <div>
      {posts.map((post) => (
        <Link key={post.slug} href={post.slug}>
          <a>{post.title}</a>
        </Link>
      ))}
      <Link href={routes.previous.slug}>
        <a>{routes.previous.name}</a>
      </Link>
      <Link href={routes.next.slug}>
        <a>{routes.next.name}</a>
      </Link>
    </div>
  )
}

export function getStaticProps() {
  const posts = getPages('posts', ['title', 'slug'])
  const routes = getRoutes(posts)
  return {
    props: {
      posts,
      routes,
    },
  }
}

And then easily navigate between them on individual pages:

import { getRoutes } from 'next-dx'
import Link from 'next/link'

export default function Index({ posts, routes }) {
  return (
    <div>
      {posts.map((post) => (
        <Link key={post.slug} href={post.slug}>
          <a>{post.title}</a>
        </Link>
      ))}
      <Link href={routes.previous.slug}>
        <a>{routes.previous.name}</a>
      </Link>
      <Link href={routes.next.slug}>
        <a>{routes.next.name}</a>
      </Link>
    </div>
  )
}

export function getStaticProps() {
  const posts = getPages('posts', ['title', 'slug'])
  const routes = getRoutes(posts)
  return {
    props: {
      posts,
      routes,
    },
  }
}

🧩 Extract TypeScript Types

There is a helper getTypes utility that utilizes ts-morph that can be used to extract type information:

import { getTypes, getPages, getPage, getPathFromSlug } from 'next-dx'

export default function ComponentDoc({ page, types }) {
  return (
    <div>
      <h1>{page.name}</h1>
      <table style={{ width: '100%', tableLayout: 'fixed' }}>
        <thead>
          <tr>
            <td>Name</td>
            <td>Description</td>
            <td>Default Value</td>
          </tr>
        </thead>
        <tbody>
          {Object.entries(types).map(([name, type], index) => {
            return (
              <tr key={index}>
                <td>{name}</td>
                <td>{type.description}</td>
                <td>{type.defaultValue?.value}</td>
              </tr>
            )
          })}
        </tbody>
      </table>
    </div>
  )
}

export const getStaticPaths = async () => {
  const pages = await getPages('components')
  return {
    paths: pages.map((page) => ({
      params: {
        slug: page.slug,
      },
    })),
    fallback: false,
  }
}

export const getStaticProps = async ({ params }) => {
  const page = await getPage('components', params.slug)
  const types = await getTypes(getPathFromSlug(params.slug))
  return {
    props: {
      page,
      types,
    },
  }
}

About

Enhance Next.js development with utilities for local and remote content.


Languages

Language:TypeScript 71.3%Language:JavaScript 28.7%