Installazione rapida
Lavora con Claude, Codex o un altro agente? Copi e incolli semplicemente il prompt qui sotto e deleghi del tutto l'installazione.
Install AddSpeech on this site by following https://addspeech.com/skill.mdQuelle istruzioni sono una pagina normale che può aprire e leggere prima di incollare qualcosa. Capisce da sé con cosa è costruito il suo progetto, chiede prima di scrivere, e nessuna parte del suo progetto ci viene inviata.
Salvando quella stessa pagina come skill, in ~/.claude/skills/addspeech/SKILL.md, potrà richiamarla per nome sul sito successivo invece di reincollare un link. È lo stesso file in entrambi i casi.
Installazione
Tutto quello che segue cambia con questa scelta: il passo di installazione, gli esempi e come si scrive ogni opzione. Viene ricordata in questo browser, così la prossima pagina si aprirà già al posto giusto.
Qualche riga in nuxt.config.ts, così il tag fa parte dell'head della sua applicazione su ogni pagina e non c'è nessun componente da ricordare.
nuxt.config.ts
export default defineNuxtConfig({
app: {
head: {
script: [
{
src: 'https://cdn.addspeech.com/widget.js',
'data-key': 'as_pub_your_key_here',
defer: true,
},
],
},
},
});Sta nel sorgente della pagina, come ci sta una publishable key di Stripe o una key di Google Maps. Una key per dominio, e in questa installazione lì è leggibile di proposito. Funziona solo sui domini elencati nel suo account, quindi chi la copia sul proprio sito non ne ricava niente.
Se preferisce che lì non ci finisca mai, la key può restare sul suo server, che consegna a ogni pagina un token di breve durata per ogni registrazione. È l'opzione session qui sotto, ed è l'installazione che consigliamo a chiunque abbia un server su cui metterla.
Non serve altro. Lasciato così, il microfono riempie la textarea della pagina - quella in cui si stava scrivendo per ultima, quando ce n'è più di una - quindi un modulo con una sola casella di messaggio non ha bisogno di nessun target. Aggiunga data-target, un selettore CSS come quello che passerebbe a querySelector, quando il campo è un input anziché una textarea, oppure quando solo una fra più textarea è la sua. Su una pagina in cui non corrisponde nulla il pulsante non compare affatto - il tag script può quindi restare nel template usato da tutte le pagine, e il microfono si mostra solo dove c'è un modulo.
Requisiti
Un elenco corto, che un sito tipico soddisfa già in gran parte.
La pagina deve essere servita in HTTPS.
I browser non danno il microfono a una pagina che non lo è, e dal nostro lato non possiamo farci niente. Localhost è escluso, quindi lo sviluppo funziona come sempre.
Il campo deve esistere nella pagina nel momento in cui lo script parte, e deve essere un vero input o textarea.
Qualcosa di modificabile che non sia un controllo di modulo - un editor rich-text costruito con dei div - non è ancora supportato.
Il campo ha bisogno di spazio per qualche migliaio di caratteri.
Le persone parlano in frasi molto più lunghe di quelle che scrivono, e un minuto di parlato normale sta intorno ai mille caratteri - quindi un maxlength di 255 o 500 si mangia in silenzio la fine di ogni risposta. Tolga l'attributo oppure lo porti intorno a 3000. Il widget controlla il campo su cui è stato puntato e lo segnala nella console del browser, e nella pagina del suo account, quando ne trova uno troppo piccolo.
La colonna dietro quel campo ha bisogno dello stesso spazio.
È la metà che di solito sfugge: un modulo che nel browser accetta novecento caratteri, davanti a un VARCHAR(255), butta via la fine all'ultimo passaggio, dopo che la persona ha già parlato. Usi TEXT, o un VARCHAR abbastanza lungo da fare sul serio, e controlli anche la regola di validazione lato server che rispecchia la vecchia lunghezza.
Qualsiasi browser degli ultimi anni.
Chrome, Edge, Firefox e Safari registrano tutti; su iOS funziona in Safari e in ogni altro browser del telefono, perché sotto sotto sono tutti Safari.
Al visitatore il microfono viene chiesto una volta, dal suo stesso browser, e la risposta viene ricordata per il suo dominio.
Quella finestra noi non la vediamo mai e non possiamo anticiparla.
Quando le risposte incluse nel mese sono finite, il pulsante si toglie dalle sue pagine fino al primo del mese successivo.
È voluto e non è un guasto. I suoi moduli e le sue aree di testo continuano a funzionare esattamente come prima che il widget fosse aggiunto, quindi un visitatore non vede alcun microfono anziché un microfono che si rifiuta. La pagina del suo account mostra quanto è stato consumato e quando la disponibilità si rinnova.
React, Vue, Livewire, WordPress, una semplice pagina HTML - non fa differenza.
Il widget scrive nel campo come farebbe una persona che digita e poi emette gli eventi input e change, quindi un framework che osserva quel campo vede esattamente quello che si aspetta di vedere.
Uso
Tutto quello che si può dire al widget, detto come attributi sul tag script. Solo la key è obbligatoria; gli altri hanno valori predefiniti scelti in modo che ometterne uno le dia qualcosa di sensato invece di qualcosa di rotto.
Le righe qui sotto chiamano ogni opzione come la chiama un tag script. Su Nuxt la stessa opzione si scrive così:
'data-theme': 'spotlight',data-keyObbligatorio
La sua key, presa dal suo account. Dice di quale sito si tratta, e quindi da quale disponibilità mensile scala la registrazione.
data-targettextarea
Un selettore CSS per il campo da riempire. Qualsiasi textarea della pagina, salvo indicazione diversa.
data-themeglow
Come il widget mostra che sta ascoltando. Glow posa una luce colorata in fondo alla finestra, spotlight attenua la pagina, subtle cambia solo il pulsante.
data-accentLa nostra
Il suo colore, in qualsiasi forma accettata dal CSS. Tutto il resto viene ricavato da lì: questo unico attributo porta il widget nella sua identità.
data-backgroundIl colore d'accento
Lo sfondo del pulsante, che è il suo colore d'accento salvo indicazione diversa. Transparent lo toglie del tutto.
data-foreground#fff
Il colore dell'icona e della parola sul pulsante. Bianco: giusto su un pulsante colorato, invisibile su uno chiaro.
data-radius999
Quanto sono arrotondati gli angoli del pulsante, in pixel. Zero è un quadrato netto; se lo omette, al massimo: un cerchio senza parola, una pastiglia con.
data-sizemedium
Quanto è grande il pulsante: small, medium o large. Un quinto più piccolo o più grande del predefinito, spostando insieme icona, parola e spazio.
data-positionright
In quale angolo sta il pulsante: top (in alto a destra), right (in basso a destra) o left (in basso a sinistra). Misurato sul campo, o sulla finestra.
data-anchorfield
Il pulsante sta nell'angolo in basso del campo che riempie. Lo metta su window per farlo galleggiare sul bordo dello schermo - meglio con sei campi.
data-showalways
Se il pulsante c'è fin dall'inizio. Always è il pulsante di sempre, focus aspetta che il cursore entri nel campo, never non aggiunge nulla.
data-devicealways
Su quali apparecchi il pulsante viene offerto: always, mobile o desktop. Mobile è puntare col dito: un tablet sì, un portatile touch no.
data-appendtrue
Ogni pressione aggiunge un nuovo paragrafo sotto quello che c'è già nel campo. Lo metta su false se ogni pressione deve sostituire la risposta precedente.
data-growfalse
Lascia crescere una textarea man mano che si riempie, così un paragrafo dettato non va riletto scorrendo all'indietro. Spento se non lo chiede.
data-labelNessuno
Una parola accanto al microfono, che il pulsante non porta se non la chiede. Auto usa la nostra dicitura; altrimenti fino a venti caratteri.
data-languageLa sua pagina
Due lettere: un suggerimento su cosa verrà detto, e la lingua che il widget parla. Viene letta dall'attributo lang della sua pagina.
data-fontNessuno
Lo metta su inherit e il pulsante prende in prestito il carattere della pagina. Se lo omette, usa un carattere di sistema arrotondato e discreto.
data-shortcuton
Ctrl+Shift+Space avvia e ferma il microfono da qualsiasi punto della pagina. Lo spenga se la sua pagina usa già quella combinazione.
data-soundoff
Un breve suono quando parte la registrazione: chime, pop o beep, o un suo file. Spento se non lo chiede - ma su un telefono è quello che arriva.
data-confettifalse
Una piccola pioggia di carta quando le parole arrivano nel campo. Spenta salvo richiesta, e mai dopo una registrazione tornata vuota.
data-counterring
Il tempo rimasto: ring attorno al pulsante, bar attraverso la finestra, o fill che sale all'interno. Ambra a dieci secondi, rosso a cinque. Attivo.
data-shadowfalse
Un'ombra sotto il pulsante. Spenta, perché quanto un controllo fluttua sulla carta l'ha già deciso il suo sito - true per chiaro su chiaro.
data-sessionNessuno
L'indirizzo, sul suo stesso sito, che distribuisce i permessi di registrazione, perché la key che consuma il suo credito resti fuori dal sorgente.
Impostazioni diverse su un campo
Tutto quello che sta qui sopra si può dire anche sul campo stesso, mettendo data-speech- davanti al nome. Al campo si chiede per primo e il tag script fa da ripiego, quindi un'eccezione costa esattamente un attributo e tutto quello che non nomina continua a seguire la pagina. Un modulo con una riga oggetto sopra un riquadro di messaggio può dare loro parole diverse, oppure stendere il conto alla rovescia lungo il bordo del campo lungo e lasciare un anello a quello corto.
<input
id="subject"
data-speech-label="Dictate"
data-speech-counter="ring"
/>
<textarea
id="message"
data-speech-anchor="field"
data-speech-counter="bar"
data-speech-grow="true"
></textarea>Il widget si veste per il campo in cui si sta scrivendo in quel momento, quindi resta un solo microfono e non uno per riquadro. La key è l'unico attributo che qui non ci sta: una seconda key su una pagina è un secondo account.
Vale la pena metterli sul campo stesso
Due attributi che vanno sul suo campo anziché sul tag script. Una trascrizione è un paragrafo che nessuno ha riletto, quindi lasci acceso il correttore ortografico del browser: la sottolineatura rossa è il modo più rapido perché chi ha appena parlato trovi quell'unico nome capito male, e correggerlo è un doppio clic. Quasi tutti i browser lo fanno già per una textarea, ma non tutti, e impostarlo esplicitamente lo rende vero ovunque. Autocapitalize mantiene le frasi digitate a mano dopo, dal telefono, coerenti con quelle dettate.
<textarea
id="message"
spellcheck="true"
autocapitalize="sentences"
rows="4"
></textarea>Aspetto
Il widget vive dentro una shadow root, che è l'unico modo affidabile per sopravvivere all'essere calati in un foglio di stile scritto da qualcun altro: niente di suo entra, e niente di nostro esce sulla sua pagina. La stessa protezione renderebbe impossibile ridisegnarlo, quindi ci sono state lasciate aperte due porte di proposito.
Custom property
Imposti una qualsiasi di queste sul widget dal suo foglio di stile e vince su quello che ha chiesto il tag script. È questo che rende possibile una modalità scura, un colore diverso per sezione del sito o una regola di stampa.
--as-accent- L'unico colore da cui viene ricavato tutto il resto.
--as-face- Lo sfondo del pulsante stesso, di norma il colore d'accento.
--as-ink- L'icona e la parola sul pulsante, di norma bianchi.
--as-deep- L'ombra sotto il pulsante, di norma una versione più scura del colore d'accento.
--as-lift- Il pulsante sotto il puntatore, di norma una versione più chiara del colore d'accento.
--as-radius- Quanto sono arrotondati gli angoli del pulsante.
--as-scale- Quanto è grande il pulsante, come semplice multiplo della sua misura normale - 0.8 è l'impostazione small, 1.2 quella large. Che sia una property e non solo un attributo è proprio il punto: si può metterla dentro una media query, così il pulsante ha una misura su un computer e un'altra sotto un pollice.
--as-font- Il carattere del pulsante e della riga di stato.
--as-hot- Il colore di una registrazione in corso, che segue il suo colore d'accento se lei non dice altrimenti. Che ci sia una registrazione in corso lo dicono l'alone che pulsa, il conto alla rovescia e la parola che lo ferma, non il colore - quindi metta qui il rosso se vuole indietro la vecchia convenzione.
addspeech-microphone {
--as-accent: #7c3aed;
--as-radius: 12px;
}
@media (prefers-color-scheme: dark) {
addspeech-microphone {
--as-accent: #a78bfa;
}
}Part
Per le cose che una custom property non riesce a esprimere: un pulsante più pesante, una riga di stato che si accorda alle sue notifiche. Ogni nome qui sotto è una promessa - come si chiama un elemento dentro il widget può cambiare a ogni rilascio, quello che lei scrive nel suo foglio di stile no.
::part(button)- Il pulsante stesso, icona e parola comprese.
::part(label)- Solo la parola sul pulsante.
::part(icon)- Solo il microfono.
::part(status)- La riga che dice cosa sta succedendo - ascolto, trascrizione, o cosa è andato storto.
::part(countdown)- La pastiglia sotto il pulsante che conta a parole gli ultimi dieci secondi.
::part(hint)- Il piccolo promemoria della scorciatoia da tastiera, mostrato mentre una registrazione è in corso.
::part(tip)- La piccola bolla sopra il pulsante che nomina la scorciatoia da tastiera, sui dispositivi con puntatore.
::part(backdrop)- Il bagliore, o la pagina attenuata dietro, a seconda del tema.
::part(bar)- La linea del conto alla rovescia lungo il bordo inferiore della finestra, quando è quello il contatore che ha scelto.
::part(badge)- Il piccolo link AddSpeech sotto il pulsante, nel piano gratuito.
addspeech-microphone::part(button) {
box-shadow: none;
font-weight: 600;
}
addspeech-microphone::part(status) {
font-family: "Your Face", sans-serif;
}Il widget porta anche il proprio stato su di sé, come semplici attributi, così può dare uno stile a un momento oltre che a un elemento.
addspeech-microphone[data-state="listening"]::part(label) {
text-transform: uppercase;
}Tutto quello che si muove è già spento per chi chiede al proprio sistema meno movimento. Ogni tema conserva la parte che dice che il microfono è acceso e perde solo la parte che si muove. Questo comportamento non va sovrascritto.
Esempi
Quattro esempi completi. Ognuno è tutto quello che deve stare sulla pagina.
Ognuno è disegnato qui sotto. Sono immagini e non microfoni funzionanti - una pagina che le chiedesse quattro permessi di registrazione mentre legge sarebbe un modo strano di difendere una sola riga di script. Quello funzionante è in home page.
La cosa più piccola che funziona
Un microfono nell'angolo in basso del campo che riempie, nel nostro colore, sull'unica textarea della pagina. Niente impostato, niente scelto.
nuxt.config.ts
script: [
{
src: 'https://cdn.addspeech.com/widget.js',
'data-key': 'as_pub_your_key_here',
defer: true,
},
],Nei suoi colori, al bordo della finestra
Che galleggia al bordo dello schermo invece di stare dentro il campo, nel suo colore, con angoli più squadrati e la sua parola accanto al microfono. Un pulsante che sta da solo è l'unico che può portare una parola: ancorato in un campo è già accanto a quello che riempie, e allora la parola sparisce.
nuxt.config.ts
script: [
{
src: 'https://cdn.addspeech.com/widget.js',
'data-key': 'as_pub_your_key_here',
'data-anchor': 'window',
'data-accent': '#7c3aed',
'data-radius': '12',
'data-label': 'Dictate',
'data-sound': 'chime',
defer: true,
},
],Su una dashboard
Sulla pagina non si muove niente tranne il pulsante che è stato premuto, la scorciatoia da tastiera viene restituita alla pagina, e il carattere è quello già caricato.
nuxt.config.ts
script: [
{
src: 'https://cdn.addspeech.com/widget.js',
'data-key': 'as_pub_your_key_here',
'data-theme': 'subtle',
'data-position': 'left',
'data-font': 'inherit',
'data-shortcut': 'off',
defer: true,
},
],Una sola risposta parlata
Per una pagina il cui unico compito è raccogliere quello che qualcuno dice: la pagina fa un passo indietro, il microfono arriva al centro, e la casella si allarga per accogliere il paragrafo che vi arriva.
nuxt.config.ts
script: [
{
src: 'https://cdn.addspeech.com/widget.js',
'data-key': 'as_pub_your_key_here',
'data-theme': 'spotlight',
'data-grow': 'true',
defer: true,
},
],Dare un nome ai suoi moduli
La pagina del suo account divide il mese per modulo: quante risposte ha raccolto ciascuno e quanto era lunga una risposta tipica. Si legge bene solo se i suoi moduli hanno un nome, ed ecco come lo ottengono.
Un modulo prende il nome dal primo di questi che esiste: un data-speech-name sul campo o sul modulo, l'id del modulo, il name del modulo, il name del campo, e in mancanza di tutto ciò l'indirizzo a cui il modulo invia. Quindi la maggior parte dei siti ottiene nomi sensati senza cambiare niente - ma la cima di quella lista è quella che controlla lei.
<form action="/customer-support/refund" data-speech-name="Refund Form">
<textarea name="reason"></textarea>
</form>Vale la pena farlo quando una pagina contiene più moduli, o quando l'id è qualcosa generato da un costruttore di pagine. "Resi" e "Reclamo" le dicono qualcosa a colpo d'occhio; "form-7ab" no.
Quando si arriva a quest'ultima risorsa viene usato solo il percorso, e di quello solo gli ultimi due segmenti. La query string cade, e ogni segmento che sembra un identificativo - un numero d'ordine, un ULID, un hash - viene sostituito con :id prima di essere salvato. Un solo modello di modulo su ottomila pagine prodotto resta un modulo solo, e nessun numero d'ordine viene mai messo per iscritto.
Niente di tutto questo riguarda la persona che compila il modulo. Quello che viene registrato è il nome del modulo e l'ora del giorno sull'orologio del visitatore, e tutti e due descrivono il suo sito e non il suo visitatore. Continua a non esserci nessuna colonna per quello che è stato detto.
Sapere che è stato dettato
Se le è utile sapere quali invii sono stati dettati invece che digitati, dia al modulo un campo nascosto chiamato _mic. Il widget riempie quel campo; non lo aggiunge mai. Un modulo che non ce l'ha si comporta esattamente come si comporta oggi.
<form method="post" action="/contact">
<textarea name="message"></textarea>
<input type="hidden" name="_mic">
</form>Viene messo a true nel momento in cui le parole atterrano nel campo, e in nessun momento prima. Chi apre il microfono e poi ci ripensa, o la cui registrazione torna vuota, invia il modulo con quel campo ancora vuoto - quindi quello che le arriva è "true" oppure niente del tutto.
Quello che vale è reale ma modesto. Dice che in questo browser è stato registrato dell'audio, che è stato mandato a noi ed è tornato con dentro delle parole, e questa è molta più fatica di quanta se ne prenda uno script che compila moduli. Il che lo rende degno di essere pesato, accanto a quello che lei già guarda.
Non è la prova che un essere umano abbia compilato il modulo, e preferiamo dirlo piuttosto che venderlo per tale. L'audio si può suonare dentro un microfono da un altoparlante, o sintetizzare del tutto da chiunque abbia voglia di dedicarci un pomeriggio. Lo tratti come tratterebbe un vasetto di miele: un segnale a buon mercato che vale la pena avere, mai la cosa che sta tra il suo modulo e il mondo.
Che fine fa la registrazione
- Non viene conservato niente. L'audio viene trascritto e buttato dentro la stessa richiesta, ogni volta - non c'è nessun secchio in cui atterra prima, e nessuna impostazione che lo cambi.
- Niente viaggia in chiaro. Un browser non dà il microfono a una pagina che non sta in HTTPS, e la registrazione arriva a noi sulla stessa connessione cifrata - quindi l'audio non è mai leggibile lungo la strada, tra chi parla e la trascrizione che torna indietro.
- Una key viene rifiutata su HTTP semplice, anche se l'indirizzo è stato aggiunto in quella forma alla lista di quelli consentiti, e non c'è nessuna impostazione che lo disattivi. L'unica eccezione è localhost, dove il traffico non lascia mai la macchina e dove le persone lavorano.
- Non si addestra niente su quello che passa di qui. Né i nostri modelli, né quelli di altri.
- Il silenzio non viene addebitato, e nemmeno una richiesta fallita dalla nostra parte.
- Se qualcosa di tutto questo dovesse cambiare, sarà scritto su questa pagina prima che accada.
Segnalare qualcuno
Dentro ogni account c'è un link. Chiunque si iscriva passando dal suo le fa guadagnare dei fills, che può assegnare al mese che preferisce.
- Si paga in fills, non in denaro. Nessuna fattura da mandare, nessuna soglia da raggiungere e nessun bonifico da aspettare - il premio è il prodotto stesso, e compare semplicemente nel suo account.
- Un'iscrizione gratuita vale 25 fills, un Freelancer 300 e un'Agency 750. Sono numeri fissi e non una percentuale, così un cambio di prezzo non modifica mai di nascosto quanto vale una segnalazione.
- Un credito è trattenuto per un mese prima di poter essere speso, e l'account che lo ha generato deve aver creato un dominio e usato davvero il microfono almeno una volta. Vale sia per le iscrizioni gratuite sia per quelle a pagamento; su un piano a pagamento l'abbonamento deve inoltre aver superato il mese, perché un pagamento con carta può ancora essere stornato.
- Decide lei in che mese finiscono. Li metta tutti sul mese prossimo se lo prevede intenso, oppure li distribuisca. Quello che un mese non consuma torna nel suo saldo quando finisce, quindi tenersi larghi non le costa niente.
- Il salvadanaio si apre per ultimo. Un sito consuma prima la propria quota mensile e solo dopo attinge ai suoi fills, per cui assegnarli non può mai rendere un mese più economico di quanto già fosse.
- Seguire il suo link non imposta nessun cookie nuovo. Il codice viene ricordato nella sessione che esiste già e sparisce alla chiusura del browser - una memoria più corta di quella abituale nel settore, e l'unica che possiamo descrivere onestamente. Lei vede quante persone sono arrivate e quante si sono iscritte; non vede mai chi.
Il suo link, i suoi clic e le sue conversioni sono sulla pagina dell'account, sotto Refer someone.
Quando non funziona
Il widget non disegna mai un errore sulla sua pagina. Se c'è qualcosa che non va nella riga che ha incollato, viene segnalato nella console del browser, preceduto dal nostro nome; per il resto non viene scritto niente. Un sito vivo non è il posto per i nostri messaggi di errore.
Un microfono che non compare affatto è quasi sempre una di tre cose: la pagina non è in HTTPS, il selettore non corrisponde a niente, oppure la key non è autorizzata su questo dominio. La console dirà quale.
Per tutto il resto, scriva a [email protected]. Per qualsiasi cosa somigli a un problema di sicurezza, scriva prima lì e ci dia la possibilità di risolverlo prima che diventi pubblico.