Fileupload
Release dato: 16.02.2026
Sist oppdatert: 18.02.2026
File upload lar brukeren laste opp vedlegg og bilder. Komponenten støtter drag and drop, filvelger, flere filer, kommentarer og forhåndsvisning av bilder. Dette krever at serveren som tar i mot skjemadataene støtter filopplasting. På mobil kan man brukeren velge å ta et bilde med kamera, eller velge en eksisterende fil.
Test komponenten
Relaterte komponenter
For fritekst når fil ikke trengs, f.eks. for kommentarer.
For feil og status ved opplasting.
For å vise fremdrift på opplasting.
Varianter
File upload kan brukes i to forskjellige typer basert på hva du forventer at brukeren skal laste opp.
| Type | Bruk |
|---|---|
| Vedlegg | Laster opp dokumenter og andre filtyper, viser filnavn i listeform |
| Bilde | Laster opp bilder og viser forhåndsvisning i kort |
File upload gir også muligheten til mer funskjonalitet i de opplastede filene (dette gjelder ikke bildevisningen).
| Funksjonalitet | Bruk |
|---|---|
| Statisk | Viser liste over filer med navn |
| Med kommentar | Viser feltet “Legg til kommentar” ved hver fil |
| Med navneendringer | Lar brukeren redigere visningsnavnet til filen |
Retningslinjer for bruk
Bruk file upload når
- brukeren skal sende inn dokumentasjon, skjema, kvitteringer eller bilder som del av en prosess
Unngå fileupload når
- du egentlig bare ber brukeren velge noe som allerede finnes i systemet, da er det bedre med select, combobox eller søk
- du bruker filopplasting som en omvei for informasjon som kunne vært fylt inn som tekst
Når skal du bruke bilde-preview i file upload?
Bruk bildevarianten (preview) når det viktigste for brukeren er å se hva bildet viser, ikke bare hvilket filnavn det har.
- Vis forhåndsvisning i et kort med filnavn og handling
- Vurder å begrense antall bilder, og fortell tydelig hvis det er en øvre grense
Vi anbefaler ikke å kombinere preview av bilder og filer, dersom bruker kan laste opp både bilder og filer, anbefaler vi vanlig listevisning av opplastede elementer.
Merk: Hvis dere bruker en streng CSP i produksjon og ønsker lokal bilde-forhåndsvisning (thumbnail), må img-src tillate blob:. Hold dette avgrenset til img-src (ikke script-src).
Gi tydelig tilbakemelding på status
Vis alltid hvilket steg filen er i: venter, laster opp, ferdig eller feilet. Det kan være lurt å bruk fremdriftsindikator for større filer eller når opplastning kan ta tid.
Husk at status også må være lesbar med skjermleser, ikke bare med farge og animasjon.
Drag and drop med alternativ
Drag and drop oppleves effektivt, men kan være vanskelig for enkelte brukere og på mobil. Selv om komponenten er fleksibel, anbefaler vi å alltid ha både drag and drop og lenke for å velge fil/bilde, og unngå å gjøre drag and drop til eneste måte å laste opp filer på.
Gjør slik
Unngå
Gi nok informasjon og riktig feilmelding
- Tillat bare relevante filformater, og vis dette eksplisitt i hjelpeteksten inne i selve feltet. Dette kan presiseres i hjelpetekst.
- Sett en fornuftig grense for filstørrelse, og forklar hvorfor store filer ikke kan lastes opp.
- Gi konkrete råd ved feil, for eksempel at brukeren kan komprimere et bilde eller lagre som et annet format.
Feilmeldingen må opptre i riktig kontekst. Gir du feil på opplastet fil skal dette vises under hele feltet. Dersom det er en feil i filen eller opplastningen feiler, skal dette vises på den aktuelle filen.
Responsivitet
File upload skal fungere godt på alle skjermstørrelser og ikke dekke for mye av innholdet.
- Dropzonen skalerer i bredde
- På små skjermer kan linjelange filnavn brytes eller trunkeres med “…”
- Drag and drop fungerer dårlig på mobil, så brukeren må ha et alternativ. Gi brukeren mulighet til å klikke på en lenke eller drop zonen med klikk.
Universell utforming
File upload er et skjemaelement og bør følge de samme prinsippene som andre felter i Punkt.
Feilmeldinger
Feilmeldinger skal være tydelige, konkrete og plassert nær feltet:
- Fortell hva som er feil, og hva brukeren må gjøre for å rette det
- Marker både komponenten og den konkrete filen som har feil
- Ikke vis feilmeldinger kun med fargeendring
Les mer om universell utforming av file upload:
Skriv gode ledetekster og instruksjoner i skjema
Tips til hvordan du skriver gode, tydelige ledetekster
Anatomi
| Element | Beskrivelse |
|---|---|
| 1. Label | Tittel/etikett over feltet (valgfritt) |
| 2. Hjelpetekst | Forklaring under feltet (valgfritt) |
| 3. Dropzone | Gir brukeren mulighet til å dra inn filer |
| 4. Beskrivende tekst | Tekst med lenke og informasjon om filformat |
| 5. Fil under opplastning | Fil som lastes opp (med progressbar) |
| 6. Ferdig opplastet fil | Fil som er lastet opp |
| 7. Handlinger | Mulighet for å legge til handlinger (rediger, kommentar eller slett) |
Implementasjon i kode
Hvordan ta komponenten i bruk?
import { PktFileUpload } from '@oslokommune/punkt-react';Testing
For web component-varianten (<pkt-fileupload>), må dere i JSDOM (eller liknende) vente til custom elementet er registrert før dere tester:
await window.customElements.whenDefined("pkt-fileupload");For React-komponenten (PktFileUpload) trengs ikke dette, men i testmiljø kan dere måtte polyfille ResizeObserver og DataTransfer.
data-testid (og andre input-attributter) videresendes til den underliggende native <input type="file">.
Bruk i skjema
Controlled eller uncontrolled?
Komponenten kan brukes på begge måter. Begge implementasjoner oppfører seg likt: sett value (+ en endringshåndterer) for controlled, eller defaultValue for uncontrolled. Hvis både value og defaultValue er satt vinner value, og begge implementasjoner logger en advarsel.
| Mode | Viktige props | Hva det gir |
|---|---|---|
| Uncontrolled | defaultValue | Enkel oppstart med intern state i komponenten. |
| Controlled | value + files-changed handler | Full kontroll i parent/store/backend-flyt. |
| Situasjon | Anbefaling | Hvorfor |
|---|---|---|
| Enkelt skjema, lokal filhåndtering | Uncontrolled | Minst mulig kode og wiring. |
| Stegskjema, global state eller autosave | Controlled | Parent kan styre reset, restore og synkronisering. |
Egen opplastingslogikk (uploadStrategy="custom") | Controlled (anbefalt) | Parent må styre filstatus og eventuelle transfer-data. |
Controlled-modus alene slår ikke på framdriftsindikatoren. Tre ting må være på plass for å vise progress per fil:
uploadStrategy="custom"— appen håndterer selve opplastingen.- Appen mater transfer-status tilbake via
transfers-propen. - Queue-en rendrer framdrift ut fra disse verdiene (skjer automatisk når de to over er satt).
Opplastingsstrategi
Uansett kan komponenten brukes på to forskjellige måter:
- med
uploadStrategy="form", hvor komponenten oppfører seg som en<input type='file' />. Brukeren velger en eller (vedmultiple) flere filer, og disse lastes opp når brukeren submitter skjemaet. - med
uploadStrategy="custom", hvor webapplikasjonen må implementere egen logikk for å laste opp filer, for eksempel via XHR. Dette gjør det mulig å vise en framdriftsindikator for opplastingen.
Både i form- og custom-modus kan komponenten ha noen tilleggsfunksjoner:
- mulighet for å angi eget filnavn (
renameFilesEnabled), hvor et ekstra input-felt lar brukeren angi et nytt filnavn - mulighet for å gi en kommentar til hver fil (
addCommentsEnabled), hvor et textarea lar brukeren skrive en kommentar i fritekst - (eksperimentelt) andre tilleggsfunksjoner kan plugges inn via
extraOperations. Hver operasjon er etQueueItemOperation-objekt med en stabilid, entitleog valgfrieonClick/renderInlineUI/renderExtendedUI/renderContent/renderHidden. Alle callbacks får et fellescontext-objekt ({ file, disabled, isActive, activate, close, getAttribute, setAttribute, inputName }), som både React og Lit deler.
Hvis opplasting av filer er påkrevd før man trykker på en eventuell submit-knapp, bruk required prop-en. Er uploadStrategy="form" settes dette på native <input type="file">, slik at nettleserens vanlige skjemavalidering brukes. Bruker man derimot uploadStrategy="custom" valideres kravet ved submit, og en feilmelding vil vises med PktAlert-komponenten.
Her er et ganske komplett eksempel på bruk av både form- og custom-varianten:
Egenskaper
Props
- Prop:
name- Type:
string- Beskrivelse:
- Navn for innsending
- Prop:
label?- Type:
string- Beskrivelse:
- Etikett/tittel over komponenten
- Prop:
helptext?- Type:
string|ReactNode- Beskrivelse:
- Hjelpetekst under etiketten
- Prop:
helptextDropdown?- Type:
string- Beskrivelse:
- Hjelpetekst som vises i en lukket boks man kan åpne
- Prop:
helptextDropdownButton?- Type:
string- Standardverdi:
"Les mer"- Beskrivelse:
- @deprecated Bruk
strings={{ forms: { readMore: '…' } }}ellersetPktStrings(). - Prop:
required?- Type:
boolean- Standardverdi:
false- Beskrivelse:
- Gjør feltet obligatorisk. I
uploadStrategy='form'brukes native validering på file input. IuploadStrategy='custom'valideres kravet ved submit og komponenten viser feilmelding hvis ingen filer er valgt. - Prop:
value?- Type:
FileItemList- Beskrivelse:
- Liste over filer i komponenten. Bruk denne for controlled-modus.
- Prop:
defaultValue?- Type:
FileItem[]- Beskrivelse:
- Default-verdi når komponenten brukes 'uncontrolled'. Ingen grunn til at denne ikke skal være tom array
[] - Prop:
onFilesChanged?- Type:
(files: FileItem[]) => void- Beskrivelse:
- Kalles når fil(er) legges til, fjernes eller oppdateres
- Prop:
uploadStrategy?- Type:
"form" | "custom"- Standardverdi:
"form"- Beskrivelse:
- Velg mellom skjemaopplasting (filene sendes når skjemaet sendes inn) og bakgrunnsopplasting (webappen håndterer opplasting via
onFileUploadRequestedog oppdaterertransfers). - Prop:
multiple?- Type:
boolean- Standardverdi:
false- Beskrivelse:
- Tillat opplasting av flere filer
- Prop:
itemRenderer?- Type:
"filename" | "thumbnail"- Standardverdi:
"filename"- Beskrivelse:
- Hvordan filer skal vises i opplastings-køen. Enten filnavn eller som thumbnails. Du kan også (eksperimentelt) lage din egen komponent.
- Prop:
optionalTag?- Type:
boolean- Beskrivelse:
- Vis 'Valgfritt'-tag ved etiketten
- Prop:
optionalText?- Type:
string- Standardverdi:
"Valgfritt"- Beskrivelse:
- @deprecated Bruk
strings={{ forms: { optional: '…' } }}ellersetPktStrings(). - Prop:
requiredTag?- Type:
boolean- Beskrivelse:
- Vis 'Må fylles ut'-tag ved etiketten
- Prop:
requiredText?- Type:
string- Standardverdi:
"Må fylles ut"- Beskrivelse:
- @deprecated Bruk
strings={{ forms: { required: '…' } }}ellersetPktStrings(). - Prop:
tagText?- Type:
string- Beskrivelse:
- Tekst som vises i en tag ved siden av label
- Prop:
disabled?- Type:
boolean- Standardverdi:
false- Beskrivelse:
- Deaktiverer hele komponenten - ingen interaksjon mulig
- Prop:
errorMessage?- Type:
string- Standardverdi:
"Det oppstod en feil ved opplastingen av fil(ene)."- Beskrivelse:
- Feilmelding for å vise under komponenten (ekstern/programmatisk feil)
- Prop:
hasError?- Type:
boolean- Standardverdi:
false- Beskrivelse:
- Om komponenten har en feiltilstand
- Prop:
allowedFormats?- Type:
string[]- Beskrivelse:
- Liste over tillatte filformater. F.eks. ['pdf', 'jpg', 'png'] eller ['image/*', 'application/pdf']
- Prop:
formatErrorMessage?- Type:
string- Beskrivelse:
- Tilpasset feilmelding ved ugyldig filtype.
- Prop:
maxFileSize?- Type:
string|number- Beskrivelse:
- Maksimal filstørrelse. F.eks. '5MB', '500KB', '1GB' eller antall bytes
- Prop:
onFileValidation?- Type:
(file: File) => string | null- Beskrivelse:
- Kjører etter innebygd format/størrelse-validering. Returner feilmeldingsstreng hvis ugyldig, null hvis gyldig.
- Prop:
onFileValidate?- Type:
(detail: FileValidateDetail) => void- Beskrivelse:
- Low-level escape hatch — Lit-paritet med
file-validate. Kalles etter innebygd validering; settdetail.errorMessagefor å avvise filen. - Prop:
sizeErrorMessage?- Type:
string- Beskrivelse:
- Tilpasset feilmelding ved for stor fil.
- Prop:
addCommentsEnabled?- Type:
boolean- Standardverdi:
false- Beskrivelse:
- La brukeren skrive en kommentar pr fil. Kommentarene postes i felter med navn
{fileupload-navn}-comment - Prop:
enableImagePreview?- Type:
boolean- Standardverdi:
false- Beskrivelse:
- Aktiver forhåndsvisning av bilder i modal (kun for thumbnail-visning)
- Prop:
extraOperations?- Type:
Array<QueueItemOperation>- Beskrivelse:
- Ekstra operasjoner pr fil (eksperimentelt). Hver operasjon er et objekt med stabil
id,titleog valgfrieonClick/renderInlineUI/renderExtendedUI/renderContent/renderHidden. Callbacks får etcontext-objekt med file, disabled, isActive, activate, close, getAttribute og setAttribute. - Prop:
fullwidth?- Type:
boolean- Standardverdi:
false- Beskrivelse:
- Om komponenten skal ta full bredde av foreldreelementet
- Prop:
onFileUploadRequested?- Type:
(fileItem: FileItem) => void- Beskrivelse:
- Ved
uploadStrategy='custom'blir denne funksjonen kalt når brukeren velger en eller flere filer. Dette lar webappen sette i gang opplasting i bakgrunnen. - Prop:
onTransferCancelled?- Type:
(fileItemId: string) => void- Beskrivelse:
- Kalles når brukeren klikker 'Slett' eller 'Avbryt'. Webappen må dermed avbryte opplastingen av denne fila.
- Prop:
renameFilesEnabled?- Type:
boolean- Standardverdi:
false- Beskrivelse:
- La brukeren angi et navn pr fil. Filnavnene postes i felter med navn
{fileupload-navn}-targetFilename - Prop:
transfers?- Type:
Array<FileTransfer>- Beskrivelse:
- Ved
uploadStrategy='custom'vil du fortelle komponenten om pågående overføringer her. Hver fil har en progress-verdi. - Prop:
truncateTail?- Type:
number- Beskrivelse:
- Hvordan lange filnavn skal forkortes med ellipse i køen. Med
4vil filnavnet vises somlangt-filnavn-med ... .pdf. Med verdi0kommer ellipsen til slutt.
Events
- Event:
files-changed- Type:
- —
- Beskrivelse:
- Elements: kalles når fil(er) legges til, fjernes eller oppdateres.
detailinneholder fil-liste og årsak. React-paritet:onFilesChanged. - Event:
file-validate- Type:
- —
- Beskrivelse:
- Elements: validerings-hook etter innebygd format/størrelse-sjekk. Lytt på eventet og sett
detail.errorMessagefor å avvise filen. React-paritet:onFileValidate. - Event:
file-upload-requested- Type:
- —
- Beskrivelse:
- Elements: kalles ved
uploadStrategy='custom'når brukeren velger fil(er).detailer enFileItem. React-paritet:onFileUploadRequested. - Event:
transfer-cancelled- Type:
- —
- Beskrivelse:
- Elements: kalles når brukeren klikker 'Slett' eller 'Avbryt'. Webappen bør avbryte pågående opplasting for
detail.fileId. React-paritet:onTransferCancelled.
En valgt fil i køen. FileItemList er en array av FileItem. Brukes som parameter i callbacks som onFileUploadRequested og i FileItemList (value / defaultValue).
- Prop:
fileId?- Type:
string- Beskrivelse:
- Unik id for filen i komponenten.
- Prop:
file?- Type:
File- Beskrivelse:
- Fil-objektet fra nettleseren.
- Prop:
attributes?- Type:
Record<string, unknown>- Beskrivelse:
- Metadata per fil (f.eks.
targetFilenamefor visningsnavn).
Status for én pågående opplasting når uploadStrategy="custom".
- Prop:
fileId?- Type:
string- Beskrivelse:
- Kobler til
FileItem.fileId. - Prop:
progress?- Type:
number|'done'|'error'|'canceled'|'queued'- Beskrivelse:
- Fremdrift (
0..1) eller tilstand. - Prop:
errorMessage?- Type:
string- Beskrivelse:
- Feilmelding ved
error. - Prop:
showProgress?- Type:
boolean- Beskrivelse:
- Vis determinate progress vs. «Laster opp…».