Search Ideas
983 ideas match your query.:
web-haptics: Haptic Feedback Finally Comes to iOS Safari
Photo by Andrew Kliatskyi on Unsplash
lochie just published a package bringing haptic feedback to the web on iOS: web-haptics. I spent four years at Apple working mostly on UIs, so I pay close attention to design and UX. In terms of presentation, use case, and attention to detail, this package comes as close to perfect as I’ve seen.
The problem
On Android, haptics have been available through navigator.vibrate(), but iOS does not support this API. There is a workaround, though – the input element with the switch attribute:
<input type="checkbox" switch>
See this switch input in action here. On iOS, the input renders not as a regular checkbox but as a switch that can be toggled on or off:

Open the link on your iPhone, tap the switch, and you’ll feel haptic feedback. As far as I know, this is currently the only known practical workaround to trigger haptic feedback on the web in iOS.
Implementation
lochie cleverly bases his package on this single workaround and pushes it to its limits. The key lines are here, creating a switch input on the fly:
js (rendered as javascript)const hapticCheckbox = document.createElement("input");hapticCheckbox.type = "checkbox";hapticCheckbox.setAttribute("switch", "");
The package also creates an associated label and clicks it to trigger haptic feedback on the connected input:
js (rendered as javascript)this.hapticLabel.click();
(My understanding is that iOS will not trigger the haptic feedback when the input is programmatically clicked – so the ‘workaround within the workaround’ is to click the associated label instead.)
Custom haptics (!)
But web-haptics can do more than just trigger a single haptic ‘pulse’. The trigger function lets you pass in your own patterns with pulses of different duration and intensity, and even delays.
Want a simple success haptic? Trigger two pulses, as shown on the package homepage:
js (rendered as javascript)trigger([{ duration: 30 },{ delay: 60, duration: 40, intensity: 1 },])
Or simply call trigger('success') as a shortcut.
Here’s an error haptic I made based on Apple’s human interface guidelines:
trigger([{ duration: 40, intensity: 0.7 },{ delay: 40, duration: 40, intensity: 0.7 },{ delay: 40, duration: 40, intensity: 0.9 },{ delay: 40, duration: 50, intensity: 0.6 },])
lochie’s website even gives you an editor to make custom haptics. As you click and drag, both pulses and code update in real time. This experience is developer bliss:

Usage
Importing the package is easy. In Rails, for example:
# config/importmap.rbpin "web-haptics", to: "https://esm.sh/web-haptics@0.0.6"
import { WebHaptics } from 'web-haptics';// In a Stimulus controller somewherelet haptics = new WebHaptics();haptics.trigger('success'); // or 'error', 'warning', etc for built-in hapticshaptics.trigger([{ duration: 40, intensity: 0.7 },{ delay: 40, duration: 40, intensity: 0.7 },])
Pass a debug option to the constructor to hear clicks in development/on desktop:
new WebHaptics({ debug: true });
Again, this package comes as close to perfect as I’ve seen. In fact, I already use it on Veritula: as you type in a text field, an error haptic plays when you exceed the max length (#4473).
I highly recommend web-haptics by lochie.
Idea: communities.
Discussions vary widely, but people gather around topics, like nutrition or software engineering. Communities would group discussions by topic, as subreddits group posts, so people can find the discussions on topics they care about.
Could live at /v/community-name.
There could be a community around nutrition, another for software engineering, a meta community for Veritula, etc.
Ben could have his own community to build his Wikipedia competitor.
Tyler suggested (#3904) we use the chart type from Kialo:

Could be a useful visualization in addition to trees.
Each top-level idea would be the center node, with its replies in segments around it. They’d be colored like the visual tree’s discs: the idea blue, criticisms red, and comments gray, solid if rationally adoptable and hollow if not.
Unlike Kialo, though, segments with the same parent would all be the same size: they’d split their parent’s arc equally between them.
Tyler suggested (#3904) we use the chart type from Kialo:

Could be a useful visualization in addition to trees.
Each top-level idea would be the center node. Then red segments around it for pending criticisms. Gray for non-pending criticisms and neutral comments.
Unlike Kialo, though, segments with the same parent would all be the same size: they’d split their parent’s arc equally between them.
Maybe one day, when Veritula makes enough to pay for this feature.
Idea: AI suggests criticisms to address before you even submit your idea.
One thing I haven’t decided yet: each circle in the graphic links to its idea, but it could instead link to its own page of incoming links.
Kitty Comes Home: my first game made with Claude Opus 5.5.
You play as a little kitten trying to find your way back to your mom.
Play for free here: https://blog.dennishackethal.com/posts/kitty-comes-home
Teaser trailer: https://youtu.be/bcM2BI-41cY
It also pays to be concise: the more you write, the more text there is to criticize. It’s in Vincent’s own interest to be less verbose. Not sure he realizes that.
This takes me back to my startup days in Berlin. It was common knowledge among founders that anyone overly worried about telling people about their great idea because someone might ‘steal’ it was a newbie founder. It’s almost always a mistake not to tell people, for several reaasons:
- Your idea probably isn’t new anyway. Somebody has probably already tried it before you and realized why it doesn’t work.
- If you don’t share your idea, you don’t get any critical feedback. You’ll make more mistakes. It will be harder to launch it.
- Most people don’t care. They have their own problems. They’re not looking to copy ideas.
Tik Tok came up with reels and then Instagram copied the feature. Arguably, Instagram does it better now. Imagine the founder of Tik Tok getting angry with Zuckerberg and trying to shame him online. That would be ridiculous.
People get angry because they hope to control more than they actually can. Ideas spread; we can’t control people’s speech. One can’t expect secrecy from people who didn’t agree to secrecy. If it’s important, like industry secrets or product launches, one should make people sign NDAs. If something is truly secret, the only person you should tell is your lawyer. Aside from that, sharing generously and openly is more profitable for you 99% of the time anyway.
Forum Rules
Veritula welcomes a wide range of discussion topics. Generally speaking, people have free speech here. Unpopular topics will not automatically get people banned. The goal of moderation is to preserve productive, truth-seeking discussion.
Behavior that is intended, or likely, to sabotage debate or prevent progress is a bannable offense. Such behavior includes, but is not limited to, harassment, brigading, rage baiting, public shaming, and persistent bad-faith argumentation or refusal to engage substantively.
Veritula takes intellectual property seriously and reserves the right to take down content that infringes on others’ intellectual property.
Veritula also reserves the right to take down obscene content such as pornography.
Content written with AI may be submitted, but only if disclosed: when posting, tick “Text written with AI?” if AI wrote any part of your idea, including polishing or translating your own writing. Veritula is a place for genuine discussion and truth-seeking, so we’d prefer to avoid talking to meat proxies without realizing it. AI content is notoriously verbose – don’t flood discussions with it. In addition, it’s your responsibility to ensure that AI detectors give negative results for content you don’t mark as written with AI. Repeat submission of content written with AI that is not disclosed and/or overly verbose is a bannable offense.
Badges reward your own contributions, so ideas written with AI don’t count toward them, disclosed or not. Badges follow the current rules, so those earned under earlier rules may be revoked.
To ensure a high quality of discussions and avoid having to refute and re-refute ideas already known to be wrong, members of Veritula are expected to make an effort to act rationally and take ideas seriously. They should stay at least somewhat up to date on discussion outcomes and avoid repeating the same discussions. Advocacy of ideas with pending criticisms and/or rejection of ideas without pending criticisms – in short, deviations from rationality as defined here – may result in a warning when someone should reasonably already know better. Repeat offenses may result in a temporary or permanent ban. Don’t rely on memory alone to decide whether to adopt an idea. Look it up on Veritula and go by whether the idea has pending criticisms – dispassionately, the way a judge would look up a law in a legal text. If you personally disagree, you can say something like: ‘Although I personally disagree, at the current state of the discussion, idea X (link to the idea on V) is (or is not) rationally adoptable.’ To make things easier, there’s a search page. You can also subscribe to notifications on an idea to stay up to date on any new criticisms (hit the bell icon in the upper right corner of an idea). You can also enable email notifications in your settings.
Serious instances of off-platform behavior that clearly would have violated these rules on-platform may result in removal.
Depending on the severity of an infraction, moderators may issue a warning, revoke badges, temporarily lock an account, or permanently ban the account.
Looking for loopholes in these rules, or abusing the letter to violate the spirit of these rules, is a bannable offense.
Moderation decisions are at the discretion of Veritula.
Users may appeal moderation decisions by contacting the moderators within a reasonable time after a decision. Appeals should explain why the decision was wrong. Appeals are reviewed at the moderators’ discretion. The same decision may be appealed only once.
Talks with moderators should remain respectful and constructive. Changes to these rules should be proposed by criticizing this idea before issues arise. Changes are generally not retroactive unless specified otherwise.
Site-wide terms and the terms of any bounty you take part in apply as well.
Your hypothetical "I'd know it when I see it" seems to test whether an animal possesses universal creativity…
More unnecessarily complicated language.
… because it could always in principle have been produced by a nonconscious program.
I don’t think that’s right. There could be animal behavior I’d have serious trouble explaining.
People asked me about this at Conjecture Con. For example, if we took an animal out of the context in which it evolved, and put it in a new context it didn’t evolve for – that’s where animals bug out – but instead of bugging out, it behaved more like a human in an unknown situation and became reflective, actually seemed to understand what was going on, that would at least give me pause.
I can’t be more specific than that because it would depend in part on new knowledge the animal would have to create in that situation, and by definition I can’t predict new knowledge. But I’d know it when I see it.
That may not be completely satisfying, but it shows that it’s simply not true that any animal behavior “could always in principle have been produced by a nonconscious program.”
To be as specific as I can though, video 15 in my series on animals and sleepwalkers shows the kind of thing I mean. The woman in the video is asleep while talking to her husband for most of the video, but toward the end she wakes up, and there’s something different in her eyes and about her attitude and responses. It’s hard to put into words, but again you know it when you see it.
… because it could always in principle have been produced by a nonconscious program.
I don’t think that’s right. There could be animal behavior I’d have serious trouble explaining.
People asked me about this at Conjecture Con. For example, if we took an animal out of the context in which it evolved, and put it in a new context it didn’t evolve for – that’s where animals bug out – but instead of bugging out, it behaved more like a human in an unknown situation and became reflective, actually seemed to understand what was going on, that would at least give me pause.
I can’t be more specific than that because it would depend in part on new knowledge the animal would have to create in that situation, and by definition I can’t predict new knowledge. But I’d know it when I see it.
That may not be completely satisfying, but it shows that it’s simply not true that any animal behavior “could always in principle have been produced by a nonconscious program.”
Humans working at an assembly line can be ‘robotic’ in the sense you describe. That’s a fair point. But then they go home and don’t act robotically.
Sleepwalkers are another example.
The claim is that animals always act robotically (outside of just plain random or buggy behavior). They can’t do otherwise. The claim is not that humans never act robotically. They do, sometimes, but they can be critical and change course.
Quote Checker now supports MLA and APA style guides, helping you quote more accurately:

Turbo 8 already does most of this. With broadcasts_refreshes and morphing, each viewer's page re-renders in their own request when a record changes, keeping scroll position and form state. Components would only save rendering and sending the rest of the page.
Make Hiccdown reactive, like Reagent: a proc as the first element marks a component, as in [->(product) { [:li, product.name] }, @product].
The server keeps track of which components each page rendered, with which records, and gives each component's element the id dom_id(record), as turbo streams do. When a record changes (after_commit, checking that it actually changed), the server tells the pages showing it, over Action Cable. Each page then requests just that component, which renders in the viewer's own request, with their user, session, locale, time zone and CSRF token, and swaps it in with a turbo stream.
Rendering the component in the request that changed the record would save that round trip, but that request has none of the viewers' context: it would render for the wrong user, or have to rebuild each viewer's context and render once per viewer.
A first pass can skip checking whether a change affects what a component shows, as when a product's name changes on a page that only shows its price.
A helper method that calls another action's helper method by name can get another helper's. Rails mixes every helper into every view, so calling index from ItemsHelper#create runs whichever helper's index Rails included last, such as PagesHelper#index:
module ItemsHelperdef index[:ul, @items.map { |i| [:li, i.name] }]enddef createindex # PagesHelper#index, not ItemsHelper#indexendend
Action names like index, show and edit are in many helpers, and the Readme encourages helper methods calling one another.
On Rails 8.1, Hiccdown's capture hands keyword arguments to the block as key-value pairs rather than as keywords. capture(text: 'foo') { |text:| text } raises ArgumentError: missing keyword: :text instead of returning 'foo', and a block that takes them as a hash, { |options| … }, gets [:text, 'foo'] instead of {text: 'foo'}.
Earlier versions of Rails pass keywords on to the block as a hash, which Hiccdown leaves alone.
Hiccdown finds an action's helper method through params[:action] rather than the controller's action_name. When a controller runs without the router, as in ProductsController.action(:show).call(env), params[:action] is nil and rendering raises NoMethodError: undefined method 'to_sym' for nil instead of calling ProductsHelper#show.
Calling render with options only, such as render status: :not_found or render layout: 'admin', skips the action's helper method and looks for an ERB template instead. Without one, it raises ActionView::MissingTemplate:
class ProductsController < ApplicationControllerdef showrender status: :not_found # MissingTemplate, though ProductsHelper#show existsendend
Naming the action works around it: render :show, status: :not_found.
Rational Decision-Making
It is rational to adopt only those ideas which, as written, don’t have pending criticisms, and to reject ideas that do.
If an idea, as written, has no pending criticisms, it’s rational to adopt it and irrational to reject it. What reason could you have to reject it? If it has no pending criticisms, then either 1) no reasons to reject it (ie, criticisms) have been suggested or 2) all suggested reasons have been addressed already.
If an idea, as written, does have pending criticisms, it’s irrational to adopt it and rational to reject it – by reference to those criticisms. What reason could you have to ignore the pending criticisms and adopt it anyway? After all, the previous paragraph applies to pending criticisms.
See also:
Tyler suggested (#3904) we use the chart type from Kialo:

Could be a useful visualization in addition to trees.
Each top-level idea would be the center node. Then red segments around it for pending criticisms. Gray for non-pending criticisms and neutral comments.
Unlike Kialo, though, each segment would have the same size as the other segments on its circle.
Offer easy way to link to latest version of an idea. The ability already exists – an idea link + /latest will always go to the latest version – but isn’t directly exposed in the form of a link or button yet.