From 062cc8d76acab0087cb1cef40f22508b55414594 Mon Sep 17 00:00:00 2001 From: Darko Gjorgjijoski Date: Wed, 29 Jul 2026 21:07:03 +0200 Subject: [PATCH 1/6] docs: document the v3 PDF changes Page setup (paper size, orientation, margins) is now honoured by both drivers rather than being a Gotenberg-only papersize string, so GOTENBERG_PAPERSIZE is replaced by the PDF_* variables and the section says the two drivers agree. Adds the v3-only capabilities: PDF/A archival output, page numbers, repeating page headers and footers via _header/_footer companion views, and overriding payment receipts and reports -- which have no picker, so a same-named file replaces the built-in outright. Custom templates now get their own copy of the line-items table rather than sharing one per type, and a missing preview image falls back to the built-in design's rather than rendering blank, so both notes change accordingly. --- docs/guide/custom-templates.md | 59 +++++++++++++++++++++++++++++----- docs/guide/pdf-generation.md | 24 +++++++++++++- 2 files changed, 74 insertions(+), 9 deletions(-) diff --git a/docs/guide/custom-templates.md b/docs/guide/custom-templates.md index 77f985b..a293446 100644 --- a/docs/guide/custom-templates.md +++ b/docs/guide/custom-templates.md @@ -43,7 +43,7 @@ Create a `.blade.php` file in the directory for its type: Any `.blade.php` file in those directories is picked up automatically and offered in the **Choose a Template** dialog. -Add a `.png` alongside it with the same name to give it a thumbnail there. Without one the tile renders blank, so it is worth adding even if you just copy the built-in preview. +Add a `.png` alongside it with the same name to control the thumbnail shown there. Without one, the preview of the built-in design is used instead. ![Custom Templates](/images/custom-templates.png) @@ -57,21 +57,64 @@ The quickest way to iterate is the `?preview` query parameter on the document's /invoices/pdf/{hash}?preview=true ``` -## The shared line-items table +## The line-items table -The built-in designs pull their line-items table from a partial, and a cloned template includes it too: +The built-in designs pull their line-items table from a partial, and a cloned template gets its own copy: ```blade -@include('pdf_templates::invoice.partials.table') +@include('pdf_templates::invoice.partials.your-template-name.table') ``` -::: warning One table, shared by all your custom templates -That partial is written once, the first time you create a custom template of a type, and every later one of that type includes the *same* file. Editing -`storage/app/templates/pdf/invoice/partials/table.blade.php` changes the table for **all** your custom invoice templates, not just the one you are working on. +It belongs to that template alone, so editing it does not affect your other designs. -If you need different tables, point each template at its own copy: create a second file next to it and change that template's `@include` to match. +## Repeating page headers and footers + +A file named after your template with a `_header` or `_footer` suffix is repeated on every page: + +``` +storage/app/templates/pdf/invoice/branded.blade.php +storage/app/templates/pdf/invoice/branded_header.blade.php +storage/app/templates/pdf/invoice/branded_footer.blade.php +``` + +These companions do not appear in the template picker; they belong to the template they are named after. + +::: warning Gotenberg only +Repeating page furniture is a Chromium capability, so it applies when the Gotenberg driver is selected. dompdf has no equivalent. ::: +They are drawn *inside* the page margin, so give the relevant margin room under **Settings → PDF Generation**, and style them inline — Chromium renders them in their own context and they inherit none of the document's CSS: + +```html +
+ Page of +
+``` + +`pageNumber` and `totalPages` are substituted by the browser. If you only want page numbers, turn them on under **Settings → PDF Generation** instead of writing a footer. + +## Overriding payment receipts and reports + +Payment receipts and the five reports have no picker: there is one design, and a custom file replaces it outright. Name the file after the document you are replacing: + +| Document | File | +|---|---| +| Payment receipt | `storage/app/templates/pdf/payment/payment.blade.php` | +| Expenses report | `storage/app/templates/pdf/reports/expenses.blade.php` | +| Profit & loss | `storage/app/templates/pdf/reports/profit-loss.blade.php` | +| Sales by customer | `storage/app/templates/pdf/reports/sales-customers.blade.php` | +| Sales by item | `storage/app/templates/pdf/reports/sales-items.blade.php` | +| Tax summary | `storage/app/templates/pdf/reports/tax-summary.blade.php` | + +`make:template` clones these too: + +```bash +php artisan make:template expenses --type=reports +php artisan make:template payment --type=payment +``` + +Payment receipts are rendered with `$payment`, `$company_address`, `$billing_address`, `$notes` and `$logo`. Reports get `$company`, `$from_date`, `$to_date`, `$currency` and their own dataset. + ## Fonts Templates get their `@font-face` rules from the packages installed under **Settings → Font Packages**, via a shared partial: diff --git a/docs/guide/pdf-generation.md b/docs/guide/pdf-generation.md index ad81652..3062dd0 100644 --- a/docs/guide/pdf-generation.md +++ b/docs/guide/pdf-generation.md @@ -55,10 +55,32 @@ Every setting can come from the environment or from **Settings → PDF Generatio | Variable | Default | Purpose | |---|---|---| | `PDF_DRIVER` | `dompdf` | `dompdf` or `gotenberg` | +| `PDF_PAPER_WIDTH` | `210mm` | Page width | +| `PDF_PAPER_HEIGHT` | `297mm` | Page height | +| `PDF_ORIENTATION` | `portrait` | `portrait` or `landscape` | +| `PDF_MARGIN_TOP` | `1.2cm` | Top page margin | +| `PDF_MARGIN_RIGHT` | `1.2cm` | Right page margin | +| `PDF_MARGIN_BOTTOM` | `1.2cm` | Bottom page margin | +| `PDF_MARGIN_LEFT` | `1.2cm` | Left page margin | +| `PDF_PAGE_NUMBERS` | `false` | Repeat the page number on every page (Gotenberg only) | | `GOTENBERG_HOST` | `http://pdf:3000` | Where the Gotenberg service listens | -| `GOTENBERG_PAPERSIZE` | `210mm 297mm` | Width and height, in `pt`, `px`, `pc`, `mm`, `cm` or `in` | +| `GOTENBERG_PDFA` | *(unset)* | `PDF/A-1b`, `PDF/A-2b` or `PDF/A-3b` for archival output | | `GOTENBERG_ALLOWED_PRIVATE_HOST` | *(unset)* | Exempts one private host from the SSRF guard — see below | +Sizes and margins are a number followed by `pt`, `px`, `pc`, `mm`, `cm` or `in`. The settings screen offers the usual paper sizes as presets, and a Custom option for anything else. + +### Page setup applies to both drivers + +Paper size, orientation and margins are honoured whichever driver renders the document, so switching between them does not change the layout. The `1.2cm` margin default is dompdf's own, which is why documents look the same after switching to Gotenberg. + +### Archival output + +Set `GOTENBERG_PDFA`, or pick a format under **Settings → PDF Generation**, to produce PDF/A. It is what you want for long-term archives, and PDF/A-3 is what the EU e-invoicing formats expect. Gotenberg only: dompdf cannot produce PDF/A. + +### Page numbers + +Turning page numbers on repeats `1 / 4` at the foot of every page. It needs a bottom margin to sit in, since the footer draws inside the page margin. A template supplying its own footer keeps it — see [custom templates](/guide/custom-templates.md). Gotenberg only. + ## Private networks and the SSRF guard Gotenberg almost always runs on a private network, and InvoiceShelf blocks private addresses by default. This is the one part of the setup that needs explaining. From 856d66cf086fcebc32e78e1e967b519ab5c8e6df Mon Sep 17 00:00:00 2001 From: Darko Gjorgjijoski Date: Sat, 1 Aug 2026 12:03:31 +0200 Subject: [PATCH 2/6] docs: page margins default to nothing The bundled templates carry their own insets, and two of them are built around a header band that runs to the paper edge -- which it can only do when there is no page margin. Documents the default and what setting a margin costs. Also flags the page-numbers consequence properly: the footer draws inside the bottom page margin, so with the new default it is invisible until one is set. --- docs/guide/custom-templates.md | 4 ++++ docs/guide/pdf-generation.md | 16 +++++++++------- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/docs/guide/custom-templates.md b/docs/guide/custom-templates.md index a293446..23d310b 100644 --- a/docs/guide/custom-templates.md +++ b/docs/guide/custom-templates.md @@ -115,6 +115,10 @@ php artisan make:template payment --type=payment Payment receipts are rendered with `$payment`, `$company_address`, `$billing_address`, `$notes` and `$logo`. Reports get `$company`, `$from_date`, `$to_date`, `$currency` and their own dataset. +## Spacing and the page edge + +The page margin defaults to nothing, so a template owns its own insets — the bundled ones use 30px. That is what lets a full-width header run to the paper edge: put it at the top of `` with no margin on `body`, and it bleeds. Set a page margin under **Settings → PDF Generation** and everything, including that header, is inset by it. + ## Fonts Templates get their `@font-face` rules from the packages installed under **Settings → Font Packages**, via a shared partial: diff --git a/docs/guide/pdf-generation.md b/docs/guide/pdf-generation.md index 3062dd0..a6070c6 100644 --- a/docs/guide/pdf-generation.md +++ b/docs/guide/pdf-generation.md @@ -58,20 +58,22 @@ Every setting can come from the environment or from **Settings → PDF Generatio | `PDF_PAPER_WIDTH` | `210mm` | Page width | | `PDF_PAPER_HEIGHT` | `297mm` | Page height | | `PDF_ORIENTATION` | `portrait` | `portrait` or `landscape` | -| `PDF_MARGIN_TOP` | `1.2cm` | Top page margin | -| `PDF_MARGIN_RIGHT` | `1.2cm` | Right page margin | -| `PDF_MARGIN_BOTTOM` | `1.2cm` | Bottom page margin | -| `PDF_MARGIN_LEFT` | `1.2cm` | Left page margin | +| `PDF_MARGIN_TOP` | `0` | Top page margin | +| `PDF_MARGIN_RIGHT` | `0` | Right page margin | +| `PDF_MARGIN_BOTTOM` | `0` | Bottom page margin | +| `PDF_MARGIN_LEFT` | `0` | Left page margin | | `PDF_PAGE_NUMBERS` | `false` | Repeat the page number on every page (Gotenberg only) | | `GOTENBERG_HOST` | `http://pdf:3000` | Where the Gotenberg service listens | | `GOTENBERG_PDFA` | *(unset)* | `PDF/A-1b`, `PDF/A-2b` or `PDF/A-3b` for archival output | | `GOTENBERG_ALLOWED_PRIVATE_HOST` | *(unset)* | Exempts one private host from the SSRF guard — see below | -Sizes and margins are a number followed by `pt`, `px`, `pc`, `mm`, `cm` or `in`. The settings screen offers the usual paper sizes as presets, and a Custom option for anything else. +Sizes are a number followed by `pt`, `px`, `pc`, `mm`, `cm` or `in`; margins may also be a bare `0`. The settings screen offers the usual paper sizes as presets, and a Custom option for anything else. + +Margins default to nothing because the bundled templates carry their own spacing, and two of them are built around a header band that runs to the paper edge — which it can only do when there is no page margin. Set a margin if you want one; the band will be inset by it. ### Page setup applies to both drivers -Paper size, orientation and margins are honoured whichever driver renders the document, so switching between them does not change the layout. The `1.2cm` margin default is dompdf's own, which is why documents look the same after switching to Gotenberg. +Paper size, orientation and margins are honoured whichever driver renders the document, so switching between them does not change the layout. ### Archival output @@ -79,7 +81,7 @@ Set `GOTENBERG_PDFA`, or pick a format under **Settings → PDF Generation**, to ### Page numbers -Turning page numbers on repeats `1 / 4` at the foot of every page. It needs a bottom margin to sit in, since the footer draws inside the page margin. A template supplying its own footer keeps it — see [custom templates](/guide/custom-templates.md). Gotenberg only. +Turning page numbers on repeats `1 / 4` at the foot of every page. **It needs a bottom margin to sit in**, since the footer draws inside the page margin and margins default to nothing — set `PDF_MARGIN_BOTTOM`, or a bottom margin under Settings, or the numbers will not appear. A template supplying its own footer keeps it — see [custom templates](/guide/custom-templates.md). Gotenberg only. ## Private networks and the SSRF guard From 9ad5b69a50a03046d4c1bc74dad70da5a2aec779 Mon Sep 17 00:00:00 2001 From: Darko Gjorgjijoski Date: Sat, 1 Aug 2026 16:15:31 +0200 Subject: [PATCH 3/6] docs: document credit notes --- docs/.vitepress/config.ts | 1 + docs/guide/credit-notes.md | 50 ++++++++++++++++++++++++++++++++++ docs/guide/custom-templates.md | 10 +++++++ docs/guide/invoices.md | 2 ++ 4 files changed, 63 insertions(+) create mode 100644 docs/guide/credit-notes.md diff --git a/docs/.vitepress/config.ts b/docs/.vitepress/config.ts index 7c2e1a9..2eff6ca 100644 --- a/docs/.vitepress/config.ts +++ b/docs/.vitepress/config.ts @@ -89,6 +89,7 @@ export default defineConfig({ { text: 'Items', link: '/guide/items.md' }, { text: 'Estimates', link: '/guide/estimates.md' }, { text: 'Invoices', link: '/guide/invoices.md' }, + { text: 'Credit Notes', link: '/guide/credit-notes.md' }, { text: 'Recurring Invoices', link: '/guide/recurring-invoices.md' }, { text: 'Payments', link: '/guide/payments.md' }, { text: 'Expenses', link: '/guide/expenses.md' }, diff --git a/docs/guide/credit-notes.md b/docs/guide/credit-notes.md new file mode 100644 index 0000000..381481c --- /dev/null +++ b/docs/guide/credit-notes.md @@ -0,0 +1,50 @@ +# Credit Notes + +A credit note reverses an invoice you have already sent. Once an invoice is out, its number is spent: correcting it by editing the original leaves a gap in your books, so accounting practice is to issue a second document that cancels the first (a *Stornorechnung*, in German bookkeeping). InvoiceShelf does exactly that. + +A credit note is a document of its own, with its own number, and it carries every amount of the original invoice negated. The two documents therefore sum to zero, which is what makes the reversal complete and auditable. + +## Creating one + +Open the invoice and choose **Create Credit Note** from its action menu. InvoiceShelf copies the invoice, negates every amount, and saves the result as a new credit note in **Draft**. + +There is nothing to fill in. A credit note always reverses its invoice in full, so it has no editable line items of its own. + +## What can be credited + +| Rule | Why | +|---|---| +| One credit note per invoice | A second reversal of the same invoice would double-count | +| An invoice cannot be credited twice, and a credit note cannot be credited | The reversal is already complete | +| Draft invoices cannot be credited | An invoice that was never issued has nothing to reverse. Edit or delete it instead | +| Invoices with recorded payments cannot be credited | Money has already changed hands. Record a refund or a correcting document instead | + +Credit notes cannot be edited after they are created. If the wrong invoice was credited, delete the credit note and the original invoice returns to its previous state, balance included. + +Deleting the invoice while its credit note still exists is blocked. Delete both together, or delete the credit note first. + +## What it does to the original invoice + +Creating the credit note settles the invoice. It drops out of the unpaid and awaiting-payment views, since nothing is owed on it any more, and its detail page shows a **Cancelled** badge that links through to the credit note. The credit note carries a matching banner linking back to the invoice it reverses. + +## Sending it + +A credit note starts as a draft and goes to the customer through the normal Send flow, the same one you use for invoices. Its email uses a credit-note template rather than the invoice one. + +The PDF renders through whichever invoice template the company uses (`invoice1`, `invoice2`, `invoice3` or a custom design), so a credit note looks like the invoice it reverses. On top of that it carries a credit-note banner, a reference line naming the original invoice and its date, and negative amounts throughout. + +::: tip Custom templates +A custom invoice template needs one include to display those banners. See [custom templates](/guide/custom-templates.md#credit-notes). +::: + +## Numbering + +Credit notes have their own sequence, independent of invoices. The default format is `CN-000001`, and creating a credit note never advances the invoice counter. + +You can change the format under **Settings → Customization → Invoices**, where a **Credit Notes** number customizer sits beside the invoice one. It works the same way: prefix, series and sequence are yours to arrange. + +## Dashboard and reports + +Credit note totals are negative, so they subtract from your sales figures automatically. A reversed invoice and its credit note cancel out, and revenue for the period reflects that. + +Invoice counts do not include credit notes, so the number of invoices you see is still the number of invoices you issued. diff --git a/docs/guide/custom-templates.md b/docs/guide/custom-templates.md index 23d310b..59bb8f7 100644 --- a/docs/guide/custom-templates.md +++ b/docs/guide/custom-templates.md @@ -93,6 +93,16 @@ They are drawn *inside* the page margin, so give the relevant margin room under `pageNumber` and `totalPages` are substituted by the browser. If you only want page numbers, turn them on under **Settings → PDF Generation** instead of writing a footer. +## Credit notes + +[Credit notes](/guide/credit-notes.md) render through the same invoice template as the document they reverse, so a custom invoice design needs one include near the top of its content area: + +```blade +@include('app.pdf.partials.credit-note-banner') +``` + +That partial draws the credit-note banner and reference line on a credit note, and the cancelled banner on an invoice that has been reversed. It renders nothing on any other document, so it is safe to leave in place. Without it the PDF still renders correctly, with negative amounts and all, but neither banner appears. + ## Overriding payment receipts and reports Payment receipts and the five reports have no picker: there is one design, and a custom file replaces it outright. Name the file after the document you are replacing: diff --git a/docs/guide/invoices.md b/docs/guide/invoices.md index 1f54930..6be64fb 100644 --- a/docs/guide/invoices.md +++ b/docs/guide/invoices.md @@ -25,6 +25,8 @@ All created invoices are shown on the Invoices page and you can easily edit or d You choose to send an invoice directly from the application or mark the invoice as sent. +An invoice you have already sent should not be edited away. To reverse one, use **Create Credit Note** from its action menu, which issues a document cancelling it in full. See [credit notes](/guide/credit-notes.md). + ![Invoices Page](/images/invoices.png) ## Invoice Lifecycle From f4deda335e9f114702b6167ed5d310976a174906 Mon Sep 17 00:00:00 2001 From: Darko Gjorgjijoski Date: Sat, 1 Aug 2026 19:53:26 +0200 Subject: [PATCH 4/6] docs(credit-notes): describe partial crediting The page described the feature as it shipped: one credit note per invoice, always the whole invoice, and never an invoice with payments on it. All three are gone. A credit note now reverses whichever lines and quantities you pick, an invoice can carry several of them until nothing is left to credit, and an invoice with payments can be credited down to its unpaid remainder. Rewritten around what the modal actually asks for, with the rules table reworked to the guards that exist today: per-line remaining quantity, the outstanding-balance cap, no crediting a fully paid invoice, and the new one that a credited invoice can no longer be edited. Adds the optional reason and the Partially credited state next to Cancelled, on screen and on the PDF. The two neighbouring pages that repeated the old "in full" claim are corrected to match. --- docs/guide/credit-notes.md | 42 ++++++++++++++++++++++++++-------- docs/guide/custom-templates.md | 2 +- docs/guide/invoices.md | 2 +- 3 files changed, 34 insertions(+), 12 deletions(-) diff --git a/docs/guide/credit-notes.md b/docs/guide/credit-notes.md index 381481c..22d1300 100644 --- a/docs/guide/credit-notes.md +++ b/docs/guide/credit-notes.md @@ -2,36 +2,58 @@ A credit note reverses an invoice you have already sent. Once an invoice is out, its number is spent: correcting it by editing the original leaves a gap in your books, so accounting practice is to issue a second document that cancels the first (a *Stornorechnung*, in German bookkeeping). InvoiceShelf does exactly that. -A credit note is a document of its own, with its own number, and it carries every amount of the original invoice negated. The two documents therefore sum to zero, which is what makes the reversal complete and auditable. +A credit note is a document of its own, with its own number, and it carries negated amounts. Reverse the whole invoice and the two documents sum to zero, which is what makes the reversal complete and auditable. Reverse part of it and the credit note carries only the part you credited. ## Creating one -Open the invoice and choose **Create Credit Note** from its action menu. InvoiceShelf copies the invoice, negates every amount, and saves the result as a new credit note in **Draft**. +Open the invoice and choose **Create Credit Note** from its action menu. A form opens listing every line of the invoice: what was invoiced, how much of it has already been credited, how much is left, and an editable quantity to credit. -There is nothing to fill in. A credit note always reverses its invoice in full, so it has no editable line items of its own. +Everything still creditable is filled in for you, so accepting the form as it opens reverses the invoice in full. That is what most credits are, and it stays a two-click job. + +To credit less, lower a quantity or clear a line's checkbox. Only the line subtotals are shown, because discounts and taxes are not yours to apportion: InvoiceShelf credits them in proportion to the lines and quantities you chose, so the credit note always agrees with the document it reverses, down to the cent. + +A **Reason** can be given and is optional. It is stored on the credit note and printed on the document, which is where an auditor will look for it. + +The result is saved as a new credit note in **Draft**. + +## Crediting an invoice more than once + +An invoice can carry several credit notes. Each one credits some of what is still left, and the quantities already credited by earlier notes are shown in the form so you always know where you stand. Crediting a line in instalments adds up to exactly what crediting it in one go would have produced. + +Once every line has been credited in full there is nothing left to reverse, and the invoice will not accept another credit note. ## What can be credited | Rule | Why | |---|---| -| One credit note per invoice | A second reversal of the same invoice would double-count | -| An invoice cannot be credited twice, and a credit note cannot be credited | The reversal is already complete | +| A line can be credited only down to the quantity that is left of it | Anything more would reverse goods that were never invoiced | +| A credit cannot exceed the amount still outstanding on the invoice | Payments have already settled part of it, and only the unpaid remainder can be reversed. A fully paid invoice cannot be credited at all; refund it instead | +| An invoice with nothing left to credit cannot be credited again | The reversal is already complete | +| A credit note cannot itself be credited | It is the reversal, not the thing being reversed | | Draft invoices cannot be credited | An invoice that was never issued has nothing to reverse. Edit or delete it instead | -| Invoices with recorded payments cannot be credited | Money has already changed hands. Record a refund or a correcting document instead | +| A credited invoice can no longer be edited | Its line items anchor the lines of every credit note that reverses it, so changing them would falsify documents already issued | -Credit notes cannot be edited after they are created. If the wrong invoice was credited, delete the credit note and the original invoice returns to its previous state, balance included. +Credit notes cannot be edited after they are created. If you credited the wrong thing, delete the credit note: the original invoice gets back exactly what that note took off it, balance included, and any other credit notes on the invoice stay as they are. -Deleting the invoice while its credit note still exists is blocked. Delete both together, or delete the credit note first. +Deleting the invoice while a credit note still reverses it is blocked. Delete both together, or delete the credit note first. ## What it does to the original invoice -Creating the credit note settles the invoice. It drops out of the unpaid and awaiting-payment views, since nothing is owed on it any more, and its detail page shows a **Cancelled** badge that links through to the credit note. The credit note carries a matching banner linking back to the invoice it reverses. +A credit note reduces the invoice's outstanding balance by the amount credited. + +Credit part of the invoice and it stays open for the remainder. Its detail page shows a **Partially credited** badge with the amount credited so far, next to its real paid status: a credit is not a payment, and an invoice that was half credited and never paid is still unpaid, just for less. + +Credit all of it and the invoice is settled. It drops out of the unpaid and awaiting-payment views, since nothing is owed on it any more, and shows a **Cancelled** badge instead. + +Both badges link through to the credit notes involved, and each credit note carries a matching banner linking back to the invoice it reverses. ## Sending it A credit note starts as a draft and goes to the customer through the normal Send flow, the same one you use for invoices. Its email uses a credit-note template rather than the invoice one. -The PDF renders through whichever invoice template the company uses (`invoice1`, `invoice2`, `invoice3` or a custom design), so a credit note looks like the invoice it reverses. On top of that it carries a credit-note banner, a reference line naming the original invoice and its date, and negative amounts throughout. +The PDF renders through whichever invoice template the company uses (`invoice1`, `invoice2`, `invoice3` or a custom design), so a credit note looks like the invoice it reverses. On top of that it carries a credit-note banner, a reference line naming the original invoice and its date, the reason if you gave one, and negative amounts throughout. + +The original invoice's PDF says what happened to it too. A partly credited invoice carries a **Partially Credited** banner naming the amount and the credit notes it came from; a fully credited one carries the **Cancelled** banner, listing every credit note that reversed it. Its totals block reports **Amount Credited** separately from **Amount Paid**, so a document settled by a credit note never claims money that was never received. ::: tip Custom templates A custom invoice template needs one include to display those banners. See [custom templates](/guide/custom-templates.md#credit-notes). diff --git a/docs/guide/custom-templates.md b/docs/guide/custom-templates.md index 59bb8f7..dff466e 100644 --- a/docs/guide/custom-templates.md +++ b/docs/guide/custom-templates.md @@ -101,7 +101,7 @@ They are drawn *inside* the page margin, so give the relevant margin room under @include('app.pdf.partials.credit-note-banner') ``` -That partial draws the credit-note banner and reference line on a credit note, and the cancelled banner on an invoice that has been reversed. It renders nothing on any other document, so it is safe to leave in place. Without it the PDF still renders correctly, with negative amounts and all, but neither banner appears. +That partial draws the credit-note banner, reference line and reason on a credit note, and the partially credited or cancelled banner on an invoice that has been reversed. It renders nothing on any other document, so it is safe to leave in place. Without it the PDF still renders correctly, with negative amounts and all, but neither banner appears. ## Overriding payment receipts and reports diff --git a/docs/guide/invoices.md b/docs/guide/invoices.md index 6be64fb..ad5e345 100644 --- a/docs/guide/invoices.md +++ b/docs/guide/invoices.md @@ -25,7 +25,7 @@ All created invoices are shown on the Invoices page and you can easily edit or d You choose to send an invoice directly from the application or mark the invoice as sent. -An invoice you have already sent should not be edited away. To reverse one, use **Create Credit Note** from its action menu, which issues a document cancelling it in full. See [credit notes](/guide/credit-notes.md). +An invoice you have already sent should not be edited away. To reverse one, use **Create Credit Note** from its action menu, which issues a document cancelling it in full or in part. See [credit notes](/guide/credit-notes.md). ![Invoices Page](/images/invoices.png) From c5a032ea21c061659f204babc75e6e32f815b161 Mon Sep 17 00:00:00 2001 From: Darko Gjorgjijoski Date: Wed, 5 Aug 2026 22:38:01 +0200 Subject: [PATCH 5/6] docs: refresh installation and development guidance --- README.md | 7 ++-- docs/developer-guide.md | 11 ++++-- docs/developer/docker.md | 81 ++++++++++++++++++++------------------ docs/developer/manual.md | 31 +++++++++------ docs/index.md | 13 ++++-- docs/install/docker.md | 83 ++++++++++++++++++++++++++++----------- docs/install/manual.md | 19 ++++++--- docs/installation.md | 15 ++++--- docs/mobile.md | 5 ++- docs/translation-guide.md | 10 ++--- 10 files changed, 171 insertions(+), 104 deletions(-) diff --git a/README.md b/README.md index ebbef4c..951c0fe 100644 --- a/README.md +++ b/README.md @@ -38,8 +38,9 @@ docker build -t invoiceshelf/docs . ## Deployment -Documentation is automatically built and published to GitHub Container Registry on every push to master. +Every push builds and publishes a commit-SHA image. Pushes to `master` also publish the +`latest` image. Images are available at: -- `ghcr.io/invoiceshelf/docs:latest` - Latest master branch -- `ghcr.io/invoiceshelf/docs:` - Specific commit builds +- `ghcr.io/invoiceshelf/docs:latest` - Latest `master` build +- `ghcr.io/invoiceshelf/docs:` - A specific commit build diff --git a/docs/developer-guide.md b/docs/developer-guide.md index 3e70ccd..a06d713 100644 --- a/docs/developer-guide.md +++ b/docs/developer-guide.md @@ -6,12 +6,15 @@ lang: en-US # Developer Guide This guide will help you set up your development environment and get started with InvoiceShelf. -There are three primary ways to install and set up InvoiceShelf for development: Docker, NGINX/PHP-FPM, and Laravel Herd. +There are three primary ways to set up InvoiceShelf for development: Docker, +NGINX/PHP-FPM, and Laravel Herd. The application currently uses Laravel 13, PHP 8.4, +Node.js 24, and pnpm. ## Docker Environment -If you want to use the pre-configured Docker dev environment +Use the application's `./devenv` wrapper to choose and start the pre-configured Docker +development environment. [[Read more]](./developer/docker.md) @@ -24,7 +27,7 @@ If you want to use Laravel Herd on your Windows/Mac machine ## Manual Nginx/php-fpm -If you want to install InvoiceShelf on plain Linux Debian/Ubuntu +Use this when you want to run the application directly on a Linux host. [[Read more]](./developer/manual.md) @@ -36,4 +39,4 @@ Hopefully one of those guides will help you get started with InvoiceShelf develo If you have any questions or run into issues, feel free to open an issue on [GitHub](https://github.com/InvoiceShelf/InvoiceShelf/issues). -Happy coding! 🧑‍💻 \ No newline at end of file +Happy coding! 🧑‍💻 diff --git a/docs/developer/docker.md b/docs/developer/docker.md index 66b0b81..cfd4240 100644 --- a/docs/developer/docker.md +++ b/docs/developer/docker.md @@ -5,57 +5,60 @@ lang: en-US # Setting Up with Docker -Using Docker is one of the easiest ways to set up InvoiceShelf for development. The necessary Docker configuration files are located in the `.dev` folder of the repository. +Using Docker is one of the easiest ways to set up InvoiceShelf for development. The +repository provides a `./devenv` wrapper that selects the supported Compose configuration, +adds the local hostname when needed, and starts the stack. The Compose files live in +`docker/development/`; `.dev` is no longer used. ## Step 1 : Clone the Repository If you forked the project, you can use the fork url instead. ```bash -git clone https://github.com/InvoiceShelf/InvoiceShelf.git +git clone --branch 3.x https://github.com/InvoiceShelf/InvoiceShelf.git cd InvoiceShelf +cp .env.example .env ``` -If you are using Linux/macOS, you need to setup the correct permissions: -```bash -chmod 775 storage/framework storage/logs bootstrap/cache -``` - -## Step 2 : Set up DNS host - -The dockerized development environment uses `invoiceshelf.test` local domain. - -This domain needs to be set up on your machine to access the default configuration. - -### a.) Linux/MacOS - -If you are using Linux or macOS, edit `/etc/hosts` as root/sudo. - -### b.) Windows +## Step 2 : Start the development environment -If you are using Windows, run Notepad as administrator and File > Open the `hosts` file in `C:Windows\System32\drivers\etc` +Run the wrapper with no arguments. It verifies Docker, adds `invoiceshelf.test` to the +hosts file when necessary (requesting sudo on Linux/macOS), then asks you to choose MySQL, +PostgreSQL, or SQLite and whether to enable Gotenberg. -### Finalize +```bash +./devenv +``` -Add the following line at the end of the hosts file to make the invoiceshelf.test available: +Your selected Compose file is saved in `.devenvconfig`. Later sessions can use: -``` -127.0.0.1 invoiceshelf.test +```bash +./devenv start +./devenv stop +./devenv logs +./devenv shell +./devenv run php artisan migrate +./devenv test +./devenv format ``` -## Step 3 : Spin up Docker +## Step 3 : Install application dependencies -To spin up the Docker environment, run: +Install PHP dependencies and generate an application key inside the running PHP container: ```bash -docker compose -f docker/development/docker-compose.mysql.yml up --build +./devenv run composer install +./devenv run php artisan key:generate ``` -Once the environment is up and running you have the following containers: +The frontend runs on the host. Install Node.js 24, enable Corepack, install the locked +dependencies, and keep the Vite development server running while you work: -- invoiceshelf-dev-php -- invoiceshelf-dev-mysql (or pgsql for sqlite) -- invoiceshelf-dev-nginx +```bash +corepack enable +pnpm install --frozen-lockfile +pnpm dev +``` ## Step 4 : Access the Application @@ -64,34 +67,36 @@ Once the containers are up and running, you can access the InvoiceShelf applicat ## Useful details -### a.) Working with composer/npm/phpunit +### a.) Working with Composer, pnpm, and tests -To access `composser`, `npm`, `vendor/bin/pint`, `vendor/bin/pest`, you need to SSH into the `invoiceshelf-dev-php` container as follows: +Use `./devenv run` to run a command in the PHP container, or use `./devenv shell` for an +interactive shell: ```bash -docker exec -it --user invoiceshelf invoiceshelf-dev-php /bin/bash +./devenv run php artisan migrate +./devenv test +./devenv format ``` ### b.) Previewing the database To see the database we use a tool called Adminer. -You can open it at http://invoiceshelf.test:8080 - -You can log in with the database details as [explained here](https://github.com/InvoiceShelf/InvoiceShelf/blob/develop/.dev/README.md#2-databases). +You can open it at `http://localhost:8080`. ### c.) Previewing Mail To see the mail we use a tool called Mailpit. -You can open it at http://invoiceshelf.test:8025 +You can open it at `http://localhost:8025`. ---   -For more details, refer to the [Docker setup README](https://github.com/InvoiceShelf/InvoiceShelf/blob/develop/.dev/README.md). +For implementation details, refer to +[docker/development](https://github.com/InvoiceShelf/InvoiceShelf/tree/3.x/docker/development).   diff --git a/docs/developer/manual.md b/docs/developer/manual.md index 9feee87..af38aaa 100644 --- a/docs/developer/manual.md +++ b/docs/developer/manual.md @@ -5,7 +5,9 @@ lang: en-US # Setting Up with NGINX/PHP-FPM -Setting up InvoiceShelf with NGINX and PHP-FPM is ideal for Linux systems. Follow the Laravel deployment guide for NGINX to set up your environment. +Setting up InvoiceShelf with NGINX and PHP-FPM is ideal for Linux systems. Follow the +[Laravel 13 NGINX deployment guide](https://laravel.com/docs/13.x/deployment#nginx) for the +web-server configuration. ## Step 1 : Install Dependencies @@ -23,13 +25,14 @@ sudo apt install nginx # Install required tools sudo apt install git curl zip unzip sqlite3 -# Install PHP/PHP-FPM -sudo apt install php8.3-fpm php8.3-gd php8.3-exif php8.3-mbstring php8.3-zip php8.3-curl php8.3-bcmath +# Install PHP 8.4/PHP-FPM and the extensions InvoiceShelf uses +sudo apt install php8.4-fpm php8.4-gd php8.4-exif php8.4-mbstring php8.4-zip php8.4-curl php8.4-bcmath php8.4-xml php8.4-intl -# Install NPM +# Install Node.js 24 and enable pnpm through Corepack curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.5/install.sh | bash -nvm install 20 -nvm use 20 +nvm install 24 +nvm use 24 +corepack enable ``` ## Step 2 : Clone the Repository @@ -37,7 +40,7 @@ nvm use 20 If you forked the project, you can use the fork url instead. ```bash -git clone https://github.com/InvoiceShelf/InvoiceShelf.git +git clone --branch 3.x https://github.com/InvoiceShelf/InvoiceShelf.git cd InvoiceShelf ``` @@ -58,11 +61,11 @@ cp .env.example .env ```bash composer install -npm install -# If you want one-time build run: -npm run prod +pnpm install +# For a one-time production build: +pnpm build # If you want dev builds run: -npm run dev +pnpm dev ``` ## Step 5 : Generate Application Key @@ -79,7 +82,9 @@ php artisan migrate ## Step 7 : Configure NGINX -Follow the Laravel guide to create NGINX server block configuration at [Laravel NGINX Deployment Guide](https://laravel.com/docs/11.x/deployment#nginx) +Follow the [Laravel 13 NGINX deployment guide](https://laravel.com/docs/13.x/deployment#nginx) +to create the NGINX server block configuration. Point the document root at the project's +`public` directory. Finally, you need to restart NGINX. @@ -93,4 +98,4 @@ Once the server is running, you can access the InvoiceShelf application in your This guide should help you get started with InvoiceShelf development. If you have any questions or run into issues, feel free to open an issue on [GitHub](https://github.com/InvoiceShelf/InvoiceShelf/issues). -Happy coding! 🧑‍💻 \ No newline at end of file +Happy coding! 🧑‍💻 diff --git a/docs/index.md b/docs/index.md index 2dae614..14cdc87 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,17 +1,22 @@ # Introduction -InvoiceShelf is an open-source web & mobile app that helps you track expenses, payments & create professional invoices & estimates. +InvoiceShelf is an open-source, self-hosted web application for creating professional +invoices and estimates, tracking payments, and managing expenses. The supported product is +the web application, built with Laravel and Vue. -Web Application is made using Laravel & VueJS while the Mobile Apps are built using React Native. +::: warning Alpha preview +These docs describe InvoiceShelf 3.x, which is still in alpha. Use the supported +2.x release for production data. +::: -## Features: +## Features - [Dashboard](./guide/dashboard.md) - [Customers](./guide/customers.md) - [Items](./guide/items.md) - [Estimates](./guide/estimates.md) - [Invoices](./guide/invoices.md) -- [Recurring-Invoices](./guide/recurring-invoices.md) +- [Recurring invoices](./guide/recurring-invoices.md) - [Payments](./guide/payments.md) - [Expenses](./guide/expenses.md) - [Taxes](./guide/taxes.md) diff --git a/docs/install/docker.md b/docs/install/docker.md index b0250b6..6e9118c 100644 --- a/docs/install/docker.md +++ b/docs/install/docker.md @@ -5,11 +5,15 @@ lang: en-US # Docker Installation -We have pre-configured [Docker image](https://hub.docker.com/r/invoiceshelf/invoiceshelf) that can be run on your computer or cloud server. +InvoiceShelf publishes production images at +[Docker Hub](https://hub.docker.com/r/invoiceshelf/invoiceshelf). The supported Compose +examples live in [InvoiceShelf/docker](https://github.com/InvoiceShelf/docker), which is +separate from the application's development Docker environment. -Follow the steps bellow to get started. +Follow the steps below to get started. -If you notice any issues report it to [InvoiceShelf/docker](https://github.com/invoiceshelf/docker). +If you notice an issue with these production images or examples, report it to +[InvoiceShelf/docker](https://github.com/InvoiceShelf/docker). ## Step 1 : Install Docker @@ -20,34 +24,53 @@ Install Docker on your host: [https://docs.docker.com/install/](https://docs.doc Open terminal and clone the repository by running: ``` -git clone https://github.com/InvoiceShelf/docker +git clone https://github.com/InvoiceShelf/docker.git +cd docker ``` ## Step 3 : Prepare docker-compose -Navigate to the cloned repository folder (`docker`) and copy one of the example files (docker-compose.{db}.yml) to docker-compose.yml +Choose a database variant and copy it to `docker-compose.yml`: -If you want to use MySQL, take `docker-compose.mysql.yml` and copy it to `docker-compose.yml` in the same folder. +```bash +# SQLite (smallest setup; no separate database service) +cp docker-compose.sqlite.yml docker-compose.yml -This will make it possible to run `docker compose up/down` commands without specifying `-f path/to/docker-compose.yml` in the `docker` folder. +# or MariaDB +cp docker-compose.mysql.yml docker-compose.yml + +# or PostgreSQL +cp docker-compose.pgsql.yml docker-compose.yml +``` + +The repository's default `docker-compose.yml` points to the SQLite variant, but copying +the selected file makes the configuration explicit and lets you use normal `docker compose` +commands without `-f`. + +The supplied files use the stable `:latest` image. For the 3.x alpha preview, +change the application image to `invoiceshelf/invoiceshelf:next` before starting +the stack. The `:next` tag is not suitable for production. -### 3.1 Reverse Proxy Requirements -For spinning up the Docker Compose stack using reverse proxies and your own domain, the following environment variables are **required**:
+### 3.1 Configure your public address + +Before starting the stack, edit `docker-compose.yml`. Set these values to the address that +your browser uses to reach InvoiceShelf. Include a non-standard port in `APP_URL` and +`SANCTUM_STATEFUL_DOMAINS`; `SESSION_DOMAIN` is the hostname only. #### APP_URL - The full public URL (including protocol and port) where your application is accessed. Used for generating absolute URLs and redirects
+ The full public URL (including protocol and port) where your application is accessed. It is used for absolute URLs and redirects. - **Format**: `https://..` - **Examples**: - `APP_URL=http://192.168.1.200` - `APP_URL=http://192.168.1.200:8080` - - `APP_URL=http://199.199.1.199` # not recommended, run behind reverse proxy with SSL - - `APP_URL=http://invoiceshelf.acme.com` # not recommended, try adding SSL + - `APP_URL=http://199.199.1.199` + - `APP_URL=http://invoiceshelf.acme.com` - `APP_URL=https://invoiceshelf.acme.com` - `APP_URL=https://invoiceshelf.acme.com:8080` #### SESSION_DOMAIN - The domain used for session cookies. Include port if using non-standard ports
+ The domain used for session cookies. Do not include a protocol or port. - **With leading dot (.)**: Allows cookies across all subdomains (e.g., `.acme.com`) - **Without dot**: Restricts cookies to specific domain only (e.g., `invoiceshelf.acme.com`) - **Format**: `..` (note the leading dot for subdomain support) @@ -56,41 +79,55 @@ For spinning up the Docker Compose stack using reverse proxies and your own doma - `SESSION_DOMAIN=invoiceshelf.acme.com` (without dot for specific domain) #### SANCTUM_STATEFUL_DOMAINS -This is comma-separated list of domains allowed to manage stateful sessions. Typically includes your frontend domain(s) and ports
+This is a comma-separated list of domains allowed to manage stateful sessions. It normally +contains the same public host as `APP_URL`, including its port when one is used. - **Format**: Comma-separated list of domains - **Examples**: - `SANCTUM_STATEFUL_DOMAINS=invoiceshelf.acme.com` - `SANCTUM_STATEFUL_DOMAINS=invoiceshelf.acme.com,invoiceshelf.acme.com:8080` - `SANCTUM_STATEFUL_DOMAINS=localhost,localhost:3000,invoiceshelf.acme.com` -**Important**: Restart the container each time after modifying these variables in `docker-compose.yaml`. +For example, a reverse-proxied installation at `https://invoices.example.com` uses: + +```yaml +- APP_URL=https://invoices.example.com +- SESSION_DOMAIN=invoices.example.com +- SANCTUM_STATEFUL_DOMAINS=invoices.example.com +``` + +Restart the stack after changing these variables. ## Step 4 : Finalize & Run docker-compose -Edit `docker-compose.yml` and adjust the configuration as per your needs. +Edit `docker-compose.yml` and replace the example database credentials before exposing the +stack publicly. You may also pin the image tag instead of relying on `latest`. And finally, open Terminal in the `docker` folder and spin up InvoiceShelf app: ``` -$ docker compose up -d +docker compose up -d ``` ## Step 5 : Complete installation wizard -Open your web browser and go to your given domain and follow the installation wizard. +Open the public address configured in `APP_URL` (for the supplied examples, +`http://localhost:8090`) and complete the installation wizard. -##### 5.1. MySQL/PostgresSQL +##### 5.1. MariaDB/PostgreSQL -For MySQL or PostgreSQL, you can use the following Database setup: +For the MariaDB or PostgreSQL Compose variants, use the values you set in +`docker-compose.yml`. The database host is the Compose service name, `database`: -- Database Host: `invoiceshelf` +- Database Host: `database` - Database Name: `invoiceshelf` - Database Username: `invoiceshelf` - Database Password: `somepass` -**Important**: The database password `somepass` is example and should be changed in the docker-compose.yml file before you run the project, especially if you expose it in public. +`somepass` is only an example. Change it, the database name, and username in both relevant +services in `docker-compose.yml` before making the installation public. ##### 5.2. SQLite Database -Leave the `database.sqlite` path as is, otherwise it will NOT work correctly. +Select SQLite and leave the database path unchanged: +`/var/www/html/storage/app/database.sqlite`. diff --git a/docs/install/manual.md b/docs/install/manual.md index c140b6e..770d2a9 100644 --- a/docs/install/manual.md +++ b/docs/install/manual.md @@ -5,18 +5,23 @@ lang: en-US # Manual Installation -Since InvoiceShelf is based on Laravel, the manual installation is very similar to Laravel. If you get stuck somewhere, you can also consult the official [Laravel guide](https://laravel.com/docs/11.x/deployment#nginx). +Since InvoiceShelf is based on Laravel 13, the manual installation is similar to a Laravel +deployment. If you get stuck, consult the official [Laravel 13 deployment guide](https://laravel.com/docs/13.x/deployment#nginx). ## Requirements ``` -PHP >= 8.2.0 +PHP >= 8.4 BCMath PHP Extension Ctype PHP Extension cURL PHP Extension DOM PHP Extension +Exif PHP Extension +Fileinfo PHP Extension Filter PHP Extension +GD PHP Extension Iconv PHP Extension +Intl PHP Extension JSON PHP Extension Mbstring PHP Extension OpenSSL PHP Extension @@ -29,7 +34,9 @@ ZIP PHP Extension ## Step 1 : Download -[Download](http://invoiceshelf.com/) the latest InvoiceShelf package. +[Download](https://invoiceshelf.com/download) the latest InvoiceShelf 3.x +preview package. Because 3.x is still alpha, use only disposable or backed-up +data. Alternatively, If you are a developer, follow the instructions to setup development environment on [this Link](../developer-guide.md) @@ -49,7 +56,7 @@ Please note that, InvoiceShelf must be installed on a primary domain or subdomai - `invoiceshelf.example.com` (Valid) - `invoiceshelf.test` (Valid) -## Step 3: Fix File Permissions +## Step 4: Fix File Permissions It is important to set the correct permissions for the storage and bootstrap/cache directories to ensure the application can write to these locations. Here are the steps: @@ -67,7 +74,7 @@ chown -R www-data:www-data storage chown -R www-data:www-data bootstrap/cache ``` -## Step 4 : Copy Environment File +## Step 5 : Copy Environment File 1. Locate the Example File: In the root directory of your project, find the file named `.env.example`. 2. Copy the `.env.example` file and create a new file named `.env` in the same root directory. @@ -88,6 +95,6 @@ By following these steps, you will create a new `.env` file that can be customiz > For example, you can change the default SQLite database to MySQL or PostgreSQL. -## Step 5 : Complete installation wizard +## Step 6 : Complete installation wizard Open the link to the domain in the browser (Example: `https://demo.invoiceshelf.com`) and complete the installation wizard as directed. diff --git a/docs/installation.md b/docs/installation.md index 706e7ae..8932100 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -5,22 +5,25 @@ lang: en-US # Installation -InvoiceShelf can be installed with Docker or Manually. +::: warning Alpha preview +InvoiceShelf 3.x is for testing and feedback. Do not use it with production +data; install the supported 2.x release when you need a production system. +::: -We usually recommend Docker because it is automatically packaged with all the required tools needed to run InvoiceShelf correct. +InvoiceShelf can be installed with Docker Compose or manually. For most self-hosted +installations, we recommend Docker Compose because the supported production images and +database variants are maintained in one place. ## Docker Installation -You can find more details about Docker Installation on the link below. +Use the official production Compose repository and choose SQLite, MariaDB, or PostgreSQL. [[Learn More]](./install/docker.md) ## Manual Installation -You can find more details about Manual Installation on the link below. +Use this option when you manage PHP, the web server, and the database yourself. [[Learn More]](./install/manual.md) - - diff --git a/docs/mobile.md b/docs/mobile.md index a8de754..232d807 100644 --- a/docs/mobile.md +++ b/docs/mobile.md @@ -1,3 +1,4 @@ -# Mobile Apps +# Mobile apps -The mobile APP is currently in development. The section will be updated as soon as we have initial version of it. +InvoiceShelf is currently available as a web application. Native mobile apps are not +available yet; this page will be updated when there is a supported mobile release. diff --git a/docs/translation-guide.md b/docs/translation-guide.md index 856f00f..d34f9ba 100644 --- a/docs/translation-guide.md +++ b/docs/translation-guide.md @@ -5,15 +5,15 @@ lang: en-US # Translation Guide -InvoiceShelf uses Crodwin.com to handle the translations. +InvoiceShelf uses [Crowdin](https://crowdin.com/) to manage translations. We welcome anyone that want to translate InvoiceShelf to their native language. -## Step 1 : Go to crowdin +## Step 1 : Go to Crowdin -Navigate to the project page on Crodwin.com. +Navigate to the InvoiceShelf project on Crowdin. -[[Navigate to Crodwin]](https://crowdin.com/project/invoiceshelf) +[[Open Crowdin]](https://crowdin.com/project/invoiceshelf) ## Step 2 : Open in Editor @@ -25,4 +25,4 @@ In the left sidebar you will see a list with languages, select your language. ## Step 4 : Start translating -You can go through each words and translate them. Do not forget to click on "Save" on each translated word. \ No newline at end of file +You can go through each words and translate them. Do not forget to click on "Save" on each translated word. From 3471c48ecba637e0f9774b7d47d52e8ac94deff2 Mon Sep 17 00:00:00 2001 From: Darko Gjorgjijoski Date: Wed, 5 Aug 2026 22:59:02 +0200 Subject: [PATCH 6/6] docs: harden manual installation setup --- docs/install/manual.md | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/docs/install/manual.md b/docs/install/manual.md index 770d2a9..c744876 100644 --- a/docs/install/manual.md +++ b/docs/install/manual.md @@ -27,6 +27,7 @@ Mbstring PHP Extension OpenSSL PHP Extension PDO PHP Extension Session PHP Extension +SQLite3 PHP Extension Tokenizer PHP Extension XML PHP Extension ZIP PHP Extension @@ -38,7 +39,8 @@ ZIP PHP Extension preview package. Because 3.x is still alpha, use only disposable or backed-up data. -Alternatively, If you are a developer, follow the instructions to setup development environment on [this Link](../developer-guide.md) +If you are a developer, follow the [development environment guide](../developer-guide.md) +instead. ## Step 2 : Upload to Server @@ -82,15 +84,12 @@ chown -R www-data:www-data bootstrap/cache ```sh cp .env.example .env ``` -3. Make sure you set APP_KEY. You can generate one using: +3. Generate a unique `APP_KEY` on the server: ```sh php artisan key:generate ``` -or generate it manually on the [following link](https://generate-random.org/laravel-key-generator). - - By following these steps, you will create a new `.env` file that can be customized with your environment-specific settings. > For example, you can change the default SQLite database to MySQL or PostgreSQL.