Skip to content

Latest commit

 

History

History

web

ElectricSQL logo

ElectricSQL - Web example

This is an example web application using ElectricSQL in the browser with wa-sqlite.

Install

Clone this repo and change directory into this folder:

git clone https://github.com/electric-sql/examples
cd examples/web

Install the dependencies:

yarn

Run

Build and run:

yarn start

Sync

The application is setup to sync via a local instance of the Electric sync service. See the docs for more information on how to run the backend locally.

Open localhost:3001 in two different browsers (so they're backed by different databases) and try it out. You'll see data being replicated between the client applications.

Notes on the code

In this example, Electric uses wa-sqlite in the browser with IndexedDB for persistence.

The main code to look at is in ./src/Example.tsx:

export const Example = () => {
  const [ db, setDb ] = useState<ElectricDatabase & { electric: ElectricNamespace }>()

  useEffect(() => {
    const init = async () => {
      const { db, electric } = await start('electric.db', '', config)
      db.electric = electric // because the hook for live queries expects `electric` to be present on the `db`
      setDb(db)
    }

    init()
  }, [])

  if (db === undefined) {
    return null
  }

  return (
    <ElectricProvider db={db}>
      <ExampleComponent />
    </ElectricProvider>
  )
}

This opens an electrified database client and passes it to the application using the React Context API. Components can then use the useElectric and useElectricQuery to access the database client and bind reactive queries to the component state. This example explicitly calls potentiallyChanged on the notifier because unlike the other drivers, the wa-sqlite driver is not proxied.

const ExampleComponent = () => {
  const db = useElectric() as ElectricDatabase & { electric: ElectricNamespace }
  const electric = db.electric
  const { results } = useElectricQuery('SELECT value FROM items', [])

  const addItem = async () => {
    await electric.adapter.run({
        sql: 'INSERT INTO items VALUES(?)',
        args: [crypto.randomUUID()]
      }
    )
    electric.notifier.potentiallyChanged()
  }

  const clearItems = async () => {
    await electric.adapter.run({
      sql : 'DELETE FROM items where true'
    })
    electric.notifier.potentiallyChanged()
  }

  return (
    <div>
      <div className='controls'>
        <button className='button' onClick={addItem}>
          Add
        </button>
        <button className='button' onClick={clearItems}>
          Clear
        </button>
      </div>
      {results && results.map((item: any, index: any) => (
        <p key={ index } className='item'>
          <code>{ item.value }</code>
        </p>
      ))}
    </div>
  )
}

More information

See the documentation and community guidelines. If you need help let us know on Discord.