Add custom widgets blog post

master
rubenwardy 2022-07-24 21:25:41 +01:00
parent 77106e596e
commit 9f3b0af22b
11 changed files with 221 additions and 29 deletions

View File

@ -0,0 +1,117 @@
---
title: Creating Your Own Custom Widgets for Renewed Tab
author: rubenwardy
layout: post
description: >-
Renewed Tab allows you to create custom widgets with your own UI and code,
isolated from the rest of the extension to improve user privacy.
images:
cover:
path: howto-custom/cover.png
edit_iframe:
path: howto-custom/edit_iframe.png
caption: The Edit Widget modal dialog
widget:
path: howto-custom/widget.png
caption: The Custom Widget
---
Renewed Tab intends to be highly customisable whilst having a good user
experience. Taken to the extreme, these two things are in conflict; the more
features you add, the harder it is to provide a good user experience. Renewed
Tab can't support every use case by itself - there's so much you could want to
support, and so little time. It would also make the download huge.
The solution to this is to allow custom user content. By making it easy for
users and third-party developers to create their own widgets and functionality,
it becomes possible to support a lot more without increasing complexity.
Renewed Tab allows you to create custom widgets using the IFrame widget. IFrames
isolate third-party code and UIs, protecting the user's privileged information
such as bookmarks and recent sites. Most browser extension stores prohibit
remote code, so using an IFrame is a requirement. This does impose some limits
on what is possible in custom widgets - you are limited to your widgets, and
can't change the UI elsewhere.
Please note that this is still **experimental** and a bit manual. In the future,
we plan to improve support for third-party widgets, making it easier for users
to use them and allowing more integration with the built-in UI.
<!-- more -->
- [Hello World widget](#hello-world-widget)
- [Get the repository](#get-the-repository)
- [Serving on localhost](#serving-on-localhost)
- [Adding to Renewed Tab](#adding-to-renewed-tab)
- [Distributing the Widget](#distributing-the-widget)
- [Conclusion](#conclusion)
## Hello World widget
Renewed Tab uses the React framework, but you're free to use whatever framework
you like. We will be using React in this tutorial. We recommend using Renewed
Tab's CSS as a basis, however, to keep a consistent theme.
### Get the repository
Clone or download [our React widget template](https://gitlab.com/renewedtab/custom_widget_template):
git clone https://gitlab.com/renewedtab/custom_widget_template
Run `npm install` to install the dependencies.
### Serving on localhost
Renewed Tab can't access files on your computer. In order to add your custom
widget to Renewed Tab, you'll need to make it available using a server of some
kind. The best way to do this locally for testing is using something called a
live HTTP server. Our example template uses webpack-dev-server for this purpose.
Run `npm start` to build the app and start the live server at
<http://localhost:8080>. Once this is done, open it in your browser to check
that it works.
### Adding to Renewed Tab
Now that you have a working live server, you can add your widget to your Renewed
Tab install. If you don't want to change your browser's New Tab for this, you
can use the [online version](https://web.renewedtab.com/).
Enter edit mode by clicking the pencil in the bottom right, click "+ Add
Widget", then click "IFrame". Find the new IFrame, hover over it, and click the
pencil to open the Edit IFrame model.
{% include figure.html img=page.images.edit_iframe %}
Set the URL to `http://localhost:8080`. You'll also probably also want to check
"Show panel background".
Press OK, you should now see the widget. Try resizing and moving the widget,
it should adapt to the available space.
{% include figure.html img=page.images.widget %}
## Distributing the Widget
Run `npm run build` to build the widget. Share the `dist/` folder publicly to
distribute your widget. A good way to do this is using GitLab pages, as it
supports updating a static website using CI.
See the `.gitlab-ci.yml` of the template. It deploys the widget to
<https://renewedtab.gitlab.io/custom_widget_template/>.
## Conclusion
Whilst support for custom widgets is in its early days, it's still possible to
do a lot of cool things with it.
In the future, we'll be adding an official plugins API which will make it super
easy to add custom widgets to Renewed Tab. Users will be able to find plugins in
the settings menu or add them by URL. Plugins will be able to add widgets to the
"Add Widgets" menu.
Make sure to share any creations you make on Twitter (#renewedtab), Discord, or
Matrix. See [Get Involved](/get_involved).

94
_sass/_syntax.scss Normal file
View File

@ -0,0 +1,94 @@
code {
padding: .2em .4em;
margin: 0;
font-size: 85%;
background-color: rgba(110,118,129,0.4);
border-radius: 6px;
color: #fff;
}
.highlight {
margin: 0 0 1em 0;
}
.highlight code {
padding: unset;
background-color: unset;
border-radius: unset;
}
/*! Darcula theme; https://github.com/alem0lars/vim-colorscheme-darcula */
.highlight .hll { background-color: #ffffcc !important; }
.highlight { color: #a9b7c6 !important; }
.highlight .c { color: #808080 !important; font-style: italic !important; } /* Comment */
.highlight .err { color: #a9b7c6 !important; } /* Error */
.highlight .g { color: #a9b7c6 !important; } /* Generic */
.highlight .k { color: #cc7832 !important; } /* Keyword */
.highlight .l { color: #a9b7c6 !important; } /* Literal */
.highlight .n, .highlight .h { color: #a9b7c6 !important; } /* Name */
.highlight .o { color: #a9b7c6 !important; } /* Operator */
.highlight .x { color: #a9b7c6 !important; } /* Other */
.highlight .p { color: #a9b7c6 !important; } /* Punctuation */
.highlight .cm { color: #808080 !important; font-style: italic !important; } /* Comment.Multiline */
.highlight .cp { color: #cc7832 !important; } /* Comment.Preproc */
.highlight .c1 { color: #808080 !important; font-style: italic !important; } /* Comment.Single */
.highlight .cs { color: #808080 !important; font-style: italic !important; } /* Comment.Special */
.highlight .gd { color: #8c0909 !important; } /* Generic.Deleted */
.highlight .ge { color: #a9b7c6 !important; text-decoration: underline !important; } /* Generic.Emph */
.highlight .gr { color: #a9b7c6 !important; } /* Generic.Error */
.highlight .gh { color: #a9b7c6 !important; font-weight: bold !important; } /* Generic.Heading */
.highlight .gi { color: #a9b7c6 !important; font-weight: bold !important; background-color: #47840d !important; } /* Generic.Inserted */
.highlight .go { color: #bfbfbf !important; background-color: #313233 !important; } /* Generic.Output */
.highlight .gp { color: #a9b7c6 !important; } /* Generic.Prompt */
.highlight .gs { color: #a9b7c6 !important; } /* Generic.Strong */
.highlight .gu { color: #a9b7c6 !important; font-weight: bold !important; } /* Generic.Subheading */
.highlight .gt { color: #ffffff !important; background-color: #990000 !important; } /* Generic.Traceback */
.highlight .kc { color: #cc7832 !important; } /* Keyword.Constant */
.highlight .kd { color: #cc7832 !important; } /* Keyword.Declaration */
.highlight .kn { color: #cc7832 !important; } /* Keyword.Namespace */
.highlight .kp { color: #cc7832 !important; } /* Keyword.Pseudo */
.highlight .kr { color: #cc7832 !important; } /* Keyword.Reserved */
.highlight .kt { color: #cc7832 !important; } /* Keyword.Type */
.highlight .ld { color: #a9b7c6 !important; } /* Literal.Date */
.highlight .m { color: #6897bb !important; } /* Literal.Number */
.highlight .s { color: #a5c25c !important; } /* Literal.String */
.highlight .na { color: #ffc66d !important; } /* Name.Attribute */
.highlight .nb { color: #cc7832 !important; } /* Name.Builtin */
.highlight .nc { color: #a9b7c6 !important; } /* Name.Class */
.highlight .no { color: #9876aa !important; } /* Name.Constant */
.highlight .nd { color: #a9b7c6 !important; } /* Name.Decorator */
.highlight .ni { color: #a9b7c6 !important; } /* Name.Entity */
.highlight .ne { color: #a9b7c6 !important; } /* Name.Exception */
.highlight .nf { color: #ffc66d !important; } /* Name.Function */
.highlight .nl { color: #a5c25c !important; } /* Name.Label */
.highlight .nn { color: #a9b7c6 !important; } /* Name.Namespace */
.highlight .nx { color: #a9b7c6 !important; } /* Name.Other */
.highlight .py { color: #a9b7c6 !important; } /* Name.Property */
.highlight .nt { color: #cc7832 !important; } /* Name.Tag */
.highlight .nv { color: #cc7832 !important; } /* Name.Variable */
.highlight .ow { color: #cc7832 !important; } /* Operator.Word */
.highlight .w { color: #a9b7c6 !important; } /* Text.Whitespace */
.highlight .mf { color: #6897bb !important; } /* Literal.Number.Float */
.highlight .mh { color: #6897bb !important; } /* Literal.Number.Hex */
.highlight .mi { color: #6897bb !important; } /* Literal.Number.Integer */
.highlight .mo { color: #6897bb !important; } /* Literal.Number.Oct */
.highlight .sb { color: #a5c25c !important; } /* Literal.String.Backtick */
.highlight .sc { color: #a5c25c !important; } /* Literal.String.Char */
.highlight .sd { color: #a5c25c !important; } /* Literal.String.Doc */
.highlight .s2 { color: #a5c25c !important; } /* Literal.String.Double */
.highlight .se { color: #a5c25c !important; } /* Literal.String.Escape */
.highlight .sh { color: #a5c25c !important; } /* Literal.String.Heredoc */
.highlight .si { color: #a5c25c !important; } /* Literal.String.Interpol */
.highlight .sx { color: #a5c25c !important; } /* Literal.String.Other */
.highlight .sr { color: #a5c25c !important; } /* Literal.String.Regex */
.highlight .s1 { color: #a5c25c !important; } /* Literal.String.Single */
.highlight .ss { color: #a5c25c !important; } /* Literal.String.Symbol */
.highlight .bp { color: #a9b7c6 !important; } /* Name.Builtin.Pseudo */
.highlight .vc { color: #cc7832 !important; } /* Name.Variable.Class */
.highlight .vg { color: #cc7832 !important; } /* Name.Variable.Global */
.highlight .vi { color: #cc7832 !important; } /* Name.Variable.Instance */
.highlight .il { color: #6897bb !important; } /* Literal.Number.Integer.Long */

View File

@ -156,16 +156,7 @@ _wrong_. Please report it below.
## How do I add custom widgets?
We would really like to support custom widgets. But unfortunately, it's not
possible due to the developer terms that Firefox and Chrome enforce on extension
developers. We're not allowed to let users upload code which runs in the
extension context.
GreaseMonkey is allowed because it runs on websites, not as an extension webpage.
We'll continue to look for alternatives for this, as we'd really like to allow it.
What you can do is use an IFrame widget to show a webpage as if it were a widget.
You can use this to create custom widgets.
See [Creating Your Own Custom Widgets for Renewed Tab](/blog/2022/07/24/custom-widgets/).
## How can I get in contact?

View File

@ -16,6 +16,7 @@ redirect_from:
- [¿Por qué no admite sincronización de navegador?](#por-qué-no-admite-sincronización-de-navegador)
- [¿Por qué no está disponible para X navegador?](#por-qué-no-está-disponible-para-x-navegador)
- [¿Por qué me sale un error al ingresar una URL personalizada en la versión web?](#por-qué-me-sale-un-error-al-ingresar-una-url-personalizada-en-la-versión-web)
- [How do I add custom widgets?](#how-do-i-add-custom-widgets)
- [Solicitudes de Funciones, Informe de Errores, y Asistencia](#solicitudes-de-funciones-informe-de-errores-y-asistencia)
@ -142,6 +143,11 @@ Nota: Si obtiene el error mientras usa la extensión del navegador, hay algo
_incorrecto_. Por favor repórtelo a continuación.
## How do I add custom widgets?
See [Creating Your Own Custom Widgets for Renewed Tab](/blog/2022/07/24/custom-widgets/).
## Solicitudes de Funciones, Informe de Errores, y Asistencia
Publicar un issue en el rastreador de problemas es la forma preferida de discutir

View File

@ -158,16 +158,8 @@ _wrong_. Please report it below.
## How do I add custom widgets?
We would really like to support custom widgets. But unfortunately, it's not
possible due to the developer terms that Firefox and Chrome enforce on extension
developers. We're not allowed to let users upload code which runs in the
extension context.
See [Creating Your Own Custom Widgets for Renewed Tab](/blog/2022/07/24/custom-widgets/).
GreaseMonkey is allowed because it runs on websites, not as an extension webpage.
We'll continue to look for alternatives for this, as we'd really like to allow it.
What you can do is use an IFrame widget to show a webpage as if it were a widget.
You can use this to create custom widgets.
## How can I get in contact?

View File

@ -158,16 +158,7 @@ _wrong_. Please report it below.
## How do I add custom widgets?
We would really like to support custom widgets. But unfortunately, it's not
possible due to the developer terms that Firefox and Chrome enforce on extension
developers. We're not allowed to let users upload code which runs in the
extension context.
GreaseMonkey is allowed because it runs on websites, not as an extension webpage.
We'll continue to look for alternatives for this, as we'd really like to allow it.
What you can do is use an IFrame widget to show a webpage as if it were a widget.
You can use this to create custom widgets.
See [Creating Your Own Custom Widgets for Renewed Tab](/blog/2022/07/24/custom-widgets/).
## How can I get in contact?

Binary file not shown.

After

Width:  |  Height:  |  Size: 537 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 999 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

View File

@ -4,3 +4,4 @@
@import "bulma";
@import "buttons";
@import "main";
@import "syntax";