Monthly Wrap Up - July

This month was spent on improving the core functionality of Petal Pro. There are two new tools: data table and route tree view, plus lots more. Check it out!


4 months ago

Watch the video version.

Or read on!


  • Accepted to speak at ElixirConf 🗣️
  • New components: Data Table & Route Tree 🧪
  • Streamlined router
  • Improved quality standards
  • Content Security Policy
  • New JS hook helpers
  • Oban jobs table
  • Roadmap updates
  • Stripe progress
  • Matt’s Petal Assist sessions still ongoing

Accepted to speak at ElixirConf 🗣️

So I applied without expecting much and was accepted! I’m not big on public speaking but since this is virtual I figured it wouldn’t be so bad. I’ll be speaking about HEEX components.


New components: Data Table & Route Tree 🧪

The route tree shows all of your routes in a simple format. You can also copy the route helper by clicking a row.

Route tree

The data table gives you a table view with sorting, filtering and pagination built in. The state is stored in the URL params.

Data table

Streamlined router

The router was a bit overwhelming so I’ve cut it down to just 92 lines. I split out some of the routes that don’t change as much into their own files (eg. auth, dev, auth routes).

Streamlined Router

Improved quality standards

I’ve added a new command mix quality. This runs three tasks:

  • mix coveralls to report your test coverage
  • mix credo to analyse your code and look for common problems
  • mix sobelow to look for potential security issues in your code

Ideally before you push your code you should run this command (along with mix format).

Content Security Policy

mix sobelow revealed to me that no Content Security Policy was being set by Phoenix. It is generally favourable to have these set to prevent XSS attacks.

Content Security Policy

You will see this in the router:

plug(:put_secure_browser_headers, %{
  "content-security-policy" =>
      struct(ContentSecurityPolicy.Policy, PetalPro.config(:content_security_policy))

Basically, in your config you need to whitelist any website you download assets from.

config :petal_pro, :content_security_policy, %{
  default_src: [

Unfortunately Alpine JS needs “unsafe-eval” to work. Because of this I have a goal to eventually remove Alpine JS altogether. The A in PETAL will have to represent “and”. Or maybe “Ash” if we end up implementing their framework.

New JS hook helpers

Dead view compatible hooks

Sometimes you want hooks to run in dead views. For example, I may want to run my tooltip library “tippy” on the landing page, which is dead (not a live view). Normally hooks can only run in a live environment, however I made a small change in app.js to run dead view compatible hooks when the page loads. This is great for small hooks that don’t communicate with a live view and just do some DOM manipulations.

import loadExternalFile from "../lib/load-external-file";

const TippyHook = {
  deadViewCompatible: true,
  mounted() {;
  updated() {;
  run(el) {
    ]).then(() => {

export default TippyHook;

Dynamically load external libraries

As you can see in the “tippy” hook code above, I run a function loadExternalFile that takes an array of URLs. This will fetch the files, but cache them so they only get fetched once. Even if you have 100 tooltips on one page, these external files will only get loaded once.

This is great because we can now easily plug in any NPM library and start using it without a build system.

Using a build system (ESBuild) and creating a package.js file to host 3rd party libraries to me is less favourable. I like not having Node as a dependency - your web app is easier to install and just feels lighter.

Oban jobs table

Next up we have an Oban jobs table. This simply is a simple version of Oban Pro. You can see your jobs and retry or cancel jobs.

Oban Jobs

Roadmap updates

Here is the leaderboard on our roadmap. Feel free to go and suggest / upvote things.

  2. Video series building a web application from start to finish
  3. API using Ash Framework
  4. Make Sidebar Layout Collapse-able
  5. Video series / articles about the implementation of new features

It seems like JSON API is used by a lot of people. I think Ash Framework makes this easy so I’m considering using that. I’ll do a poll on Twitter in the coming weeks as to whether or not to use Ash.

Stripe progress

As I was building Stripe I kept noticing things that needed fixing and hence this has been delayed further. I really want Petal Pro to have a solid foundation and if I feel like something is off then I would rather patch that up before adding more and more functionality.

So far I have:

  1. settled on a data model and which information I should store locally from Stripe
  2. enabled a 1-way sync of products from Stripe (you will CRUD on Stripe, and pull them down into your application)
  3. setup webhooks to work with Oban - this means if a webhook fails you will see it as a failed job

Thanks - see you next month!

Remember, in the video you can add comments and reactions to all of this - so let us know your thoughts if you have any.

Thanks for reading