ComfyCoders TranquilTools
Docs /Laravel Vue CrudBuilder
Repository
v1

Vue Pages

Per-resource pages (default)

make:crud generates Index.vue, Show.vue and Form.vue inside a folder named after the resource:

resources/js/pages/Users/Index.vue
resources/js/pages/Users/Show.vue
resources/js/pages/Users/Form.vue

The directory follows your project's convention - resources/js/pages/ or resources/js/Pages/, detected the same way as for the shared pages (see Installation). Existing files are never overwritten unless you pass --force.

<!-- Users/Index.vue -->
<script setup lang="ts">
import TableBuilder from '@table-builder/components/TableBuilder.vue'
import type { TableData } from '@table-builder/types/table-builder'
import { useTranslations } from '@table-builder/composables/useTranslations'
import { Link } from '@inertiajs/vue3'

defineProps<{
    table: TableData
    title: string
    createRoute: string
}>()

const { t } = useTranslations('vue_crud_builder_translations')
</script>
<!-- Users/Form.vue -->
<script setup lang="ts">
import { router } from '@inertiajs/vue3'
import Form from '@form-builder/components/Form.vue'
import type { FormSchema } from '@form-builder/types/form-builder'
import { useTranslations } from '@table-builder/composables/useTranslations'

const props = defineProps<{
    form: FormSchema
    title: string
    destroyRoute?: string
    destroyLabel?: string
    destroyConfirm?: string
}>()

const { t } = useTranslations('vue_crud_builder_translations')
</script>
<!-- Users/Show.vue -->
<script setup lang="ts">
import { useTranslations } from '@table-builder/composables/useTranslations'
import { Link } from '@inertiajs/vue3'

defineProps<{
    record: Record<string, unknown>
    title: string
    editRoute: string
    indexRoute: string
}>()

const { t } = useTranslations('vue_crud_builder_translations')
</script>

The @table-builder and @form-builder imports rely on the Vite aliases the installer adds - see Installation. Labels such as the create/edit/back buttons come from the package translations shared with Inertia as vue_crud_builder_translations.

Shared pages

Instead of generating per-resource pages, publish a single set of Crud/*.vue pages and reuse them across all CRUD resources.

Publish the shared pages once:

php artisan vendor:publish --tag=crud-builder-pages

This copies:

resources/js/pages/Crud/Index.vue
resources/js/pages/Crud/Show.vue
resources/js/pages/Crud/Form.vue

The destination follows your project's convention: resources/js/pages/Crud/ or resources/js/Pages/Crud/, whichever directory exists (see Installation). Run npm run build afterwards.

Then set the config so make:crud uses them by default:

// config/vue-crud-builder.php
'pages' => 'shared',

Or pass --shared per command:

php artisan make:crud Product --shared

Choosing the page style

The pages config key controls the default behaviour:

Value Behaviour
per-resource Always generate per-resource pages
shared Always use the published shared pages
ask Prompt during make:crud (default)

The ask prompt itself defaults to per-resource.

Pass --pages or --shared to override the config for a single run.

Delete button on the edit form

Both the shared Crud/Form.vue and the generated per-resource Form.vue render an optional delete button when they receive a destroyRoute prop. The controller's edit() method passes it:

return Inertia::render('Products/Form', [
    'form' => $form,
    'title' => 'Edit Product',
    'destroyRoute' => route('products.destroy', $product),
]);

The button is only rendered when destroyRoute is present, and it asks for confirmation before issuing router.delete(). Two additional optional props override the copy, which otherwise comes from the package translations:

Prop Falls back to translation key English default
destroyLabel delete Delete
destroyConfirm delete_confirm Are you sure you want to delete this record?

make:crud prompts whether to include this automatically, or pass --destroy to skip the prompt.

destroyRoute is optional on both pages, so a Form page generated without --destroy renders and type-checks with no delete button at all.