Sorry for disturbing the staff at Anvil for the third time in a day but I was wondering if it is possible for me to prevent copying text from my website. I’m building a community for writers to share their works so that readers can read them. And if people can easily copy the text, it will be highly risky. Books getting stolen from online platforms is very common.
I tried pasting a transparent png image over the text but it can still be copied by dragging the mouse to copy text from an area.
There are various techniques using CSS or Javascript to disable text selection, disable the right-click menu, unbind or catch the keyboard text selection, but these are just deterrents to casual users and can be bypassed. There are also obfuscation techniques to make it harder for people looking at your page source. But short of using DRM, public key encryption, etc. I’m not aware of any absolute way to prevent plain text from being copied from a web resource.
I used a converter tool that converted my Anvil website into an app version. It had the option of disabling selecting text which worked well. Is there a way to imply it to my website as well?
Also, my knowledge of Java and CSS is limited so if you know a way, even if it is not completely foolproof, please tell me.
I was also hoping for some way by which I can make my text show up in an image instead(I know that it still isn’t completely safe but it will be the best option for now)
There’s a CSS rule that allows you to say the user should not be able to select text in the element:
user-select: none;
That would need put into an Anvil role and then the particular text components assigned that role. There’s information on creating your own roles at: Anvil Docs | Themes and Styling
I don’t know how widely browsers support user-select, so you’d want to test that on a variety of web browsers.
The user select option will work well with Google Chrome and Microsoft Edge. However, browsers like UC browser can easily copy the text.
Although if anyone here is good with HTML and CSS, I’ll like to insert a Transparent PNG upon my entire page. XY panel will totally mess up my formatting for mobile so it will not be my preference. Is there a way to achieve this using HTML so that the transparent PNG will be over my entire website? This will be able to disable copy-pasting.
Also, I don’t know why but canvas is not working for me. I literally just pasted the code from example and yet nothing happened.
If it’s just a deterrent you could also combine the user select option with a pseudo ::before
.structure::before {
/* Or .anvil-role-unselectable::before instead of the whole page */
content: "";
width: 100%;
height: 100%;
position: absolute;
z-index: 3;
}
Though as @kcampbell points out - someone determined can copy the content.
All they need to do is inspect the html
Re the canvas - make sure you put that code in the canvas show event, or better the canvas reset event.
You can only draw on a canvas when it’s on the screen.
I’m confused about that ::before function you mentioned. What does it do?
Also, I tried Canvas but it doesn’t work as efficiently as a label. I didn’t find any option to change text and the they also come in a single line. I don’t think it is suitable for huge amount of text inside it
It’s a bit of a hack - you typically use it for elements that are associated with another element.
The way it’s written above effectively creates a transparent layer over the .structure element (in anvil’s case the whole app)
Using it as a role would create a transparent layer over the Anvil Component
It worked better. Thanks. Also, do you think adding text to image using PIL will work better than Canvas? I haven’t upgraded my plan yet but I plan to do it
Yes you’d need to use a third party python library to convert a pdf to an image. There are a few libraries with this functionality out there and most will be available on the full runtime.
e.g.
from pdf2image import convert_from_bytes
import io
import anvil.media
@anvil.server.callable
def create_pdf():
# Create a pdf from 'Form2', and pass in 'name' and 'img' as its constructors
pdf = anvil.pdf.render_form("Form2")
images = convert_from_bytes(pdf.get_bytes())
image = images[0]
b = io.BytesIO()
image.save(b, 'PNG')
return anvil.BlobMedia('image/png', b.getvalue())