Skip to content

Instantly share code, notes, and snippets.

@innocenzi
Last active April 5, 2025 13:08
Show Gist options
  • Select an option

  • Save innocenzi/5334b9679c35465defe72bdb57dd541c to your computer and use it in GitHub Desktop.

Select an option

Save innocenzi/5334b9679c35465defe72bdb57dd541c to your computer and use it in GitHub Desktop.

Revisions

  1. innocenzi revised this gist Jul 18, 2022. No changes.
  2. innocenzi created this gist Jul 18, 2022.
    30 changes: 30 additions & 0 deletions inertia-layout.ts
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,30 @@
    import type { Plugin } from 'vite'

    const PLUGIN_NAME = 'vite:inertia:layout'
    const TEMPLATE_LAYOUT_REGEX = /<template +layout(?: *= *['"](?:(?:(\w+):)?(\w+))['"] *)?>/

    export default (): Plugin => ({
    name: PLUGIN_NAME,
    transform: (code: string) => {
    if (!TEMPLATE_LAYOUT_REGEX.test(code)) {
    return
    }

    const isTypeScript = /lang=['"]ts['"]/.test(code)

    return code.replace(TEMPLATE_LAYOUT_REGEX, (_, domainName, layoutName) => {
    const resolvedLayoutName = layoutName ?? 'default'
    const layout = domainName
    ? `@/domains/${domainName}/layouts/${resolvedLayoutName}.vue`
    : `@/layouts/${resolvedLayoutName}.vue`

    return `
    <script${isTypeScript ? ' lang="ts"' : ''}>
    import layout from '${layout}'
    export default { layout }
    </script>
    <template>
    `
    })
    },
    })
    29 changes: 29 additions & 0 deletions resolve-page-component.ts
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,29 @@
    export async function resolvePageComponent(name: string, pages: Record<string, any>, defaultLayout?: any) {
    const mapped: string[] = []
    const path = Object.keys(pages)
    .sort((a, b) => a.length - b.length)
    .find((path) => {
    mapped.push(
    path = path
    .replace('../domains/', '')
    .replace('/pages/', '/')
    .replace('.vue', '')
    .replace('/', '.'),
    )

    return path === name
    })

    if (!path) {
    throw new Error(`Page component "${name}" could not be found. Available pages: \n- ${mapped.join('\n- ')}`)
    }

    let component = typeof pages[path] === 'function'
    ? await pages[path]()
    : pages[path]

    component = component.default ?? component
    component.layout ??= defaultLayout

    return component
    }